为了账号安全,请及时绑定邮箱和手机立即绑定

将结构切片转换为字符串的二维切片

将结构切片转换为字符串的二维切片

Go
缥缈止盈 2022-04-26 19:45:29
我想从数据库中获取数据并写入 excel假设我有一个像这样的结构:type user struct {    ID    int64    Name  string    Age   int}我可以获得指向用户类型表单 DB 的切片的指针&[]user{}但我想将该切片转换为字符串的二维切片[][]string{}这是我的代码尝试做这样的工作:func toStrings(slice interface{}) [][]string {    switch reflect.TypeOf(slice).Elem().Kind() {    case reflect.Slice:        ret := [][]string{}        val := reflect.ValueOf(slice).Elem()        for i := 0; i < val.Len(); i++ {            tempSlice := []string{}            tempV := reflect.ValueOf(val.Index(i))            for j := 0; j < tempV.NumField(); j++ {                tempSlice = append(tempSlice, tempV.Field(j).String())            }            ret = append(ret, tempSlice)        }        return ret    }    return nil}但是从上面的代码中我得到的是一个像[<*reflect.rtype Value> <unsafe.Pointer Value> <reflect.flag Value>]我哪里做错了?
查看完整描述

3 回答

?
HUX布斯

TA贡献1876条经验 获得超6个赞

对不起,我发现我做错了,我tempV错了


func toStrings(slice interface{}) [][]string {

    switch reflect.TypeOf(slice).Elem().Kind() {

    case reflect.Slice:

        ret := [][]string{}

        val := reflect.ValueOf(slice).Elem()

        for i := 0; i < val.Len(); i++ {


            tempSlice := []string{}


            // tempV should be:

            tempV := val.Index(i)

            // instead of reflect.ValueOf(val.Index(i))


            for j := 0; j < tempV.NumField(); j++ {

                tempSlice = append(tempSlice, tempV.Field(j).String())

            }


            ret = append(ret, tempSlice)

        }

        return ret

    }

    return nil


}


查看完整回答
反对 回复 2022-04-26
?
千巷猫影

TA贡献1829条经验 获得超7个赞

也许我有一个简单的方法来解决问题,golang playground here


我曾经encoding/json转换为json数据,然后将其转换为map[string]interface{}。


func toStrings2(slice interface{}) [][]string {

    jsonData, _ := json.Marshal(slice)

    var out []map[string]interface{}

    _ = json.Unmarshal(jsonData, &out)

    var fields []string

    if len(out) > 0 {

        for k := range out[0] {

            fields = append(fields, k)

        }

    }

    var ret [][]string

    for _, row := range out {

        var r []string

        for _, k := range fields {

            r = append(r, fmt.Sprint(row[k]))

        }

        ret = append(ret, r)

    }

    return ret

}

注意:


在@CeriseLimón 的帮助下,我知道此答案中的代码无法处理 User.ID 的大值。


查看完整回答
反对 回复 2022-04-26
?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

问题中的代码有两个问题。第一个问题是 slice 元素被表达式中的 aa reflect.Value 双重包裹reflect.Value(val.Index(i))。通过删除对 reflect.Value 的额外调用来修复。第二个问题是reflect.Value String方法不会将基础值转换为其字符串表示形式。使用 fmt.Sprint(或其朋友之一)来做到这一点。


试试这个:


func toStrings(slice interface{}) [][]string {

    // Get reflect value for slice. Use Indirect to

    // handle slice argument and pointer to slice

    // argument.

    v := reflect.Indirect(reflect.ValueOf(slice))

    if v.Kind() != reflect.Slice {

        return nil

    }


    var result [][]string


    // For each element...

    for i := 0; i < v.Len(); i++ {


        // Get reflect value for slice element (a struct). Use

        // Indirect to handle slice of struct and slice of

        // pointer to struct.

        e := reflect.Indirect(v.Index(i))

        if e.Kind() != reflect.Struct {

            return nil

        }


        // Convert fields to string and append.

        var element []string

        for i := 0; i < e.NumField(); i++ {

            // Use fmt.Sprint to convert arbitrary Go value

            // to a string.

            element = append(element, fmt.Sprint(e.Field(i).Interface()))

        }


        result = append(result, element)

    }

    return result

}


查看完整回答
反对 回复 2022-04-26
  • 3 回答
  • 0 关注
  • 146 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信