访问函数内结构的指针值

时间:2017-04-14 07:09:51

标签: go reflection

我想将一个struct对象传递给一个函数&能够从该函数访问其指针值。我无法理解为什么以下导致错误。

func GetStructFieldPointers(u interface{}, jsonFields []string) []interface{} {
    structVal := reflect.ValueOf(&u).Elem()
    structType := reflect.TypeOf(u)
    numberOfFields := structVal.NumField() // getting error here reflect:
                                           // call of reflect.Value.NumField
                                           // on interface Value
    numberOfJSONFields := len(jsonFields)
    res := make([]interface{}, numberOfJSONFields)
    fmt.Println(jsonFields)
    for fieldIndex, field := range jsonFields {
        for i := 0; i < numberOfFields; i++ {
            if structType.Field(i).Tag.Get("json") == field {
                valueField := structVal.Field(i)
                res[fieldIndex] = valueField.Addr().Interface()
            }
        }
    }

    return res
}

type User struct {
    Id             int      `json:"id"`
    Name           string   `json:"name"`
    Address        string   `json:"address"`
}
user := User{}
res := GetStructFieldPointers(user, []string{"id", "name"}) 

为了完成这项工作,我必须将structType作为参数,如下所示:

func GetStructFieldPointers(u interface{}, structType reflect.Type, jsonFields []string) []interface{} {
    structVal := reflect.ValueOf(u).Elem()
    // structType := reflect.TypeOf(u)
    numberOfFields := structVal.NumField() 
    numberOfJSONFields := len(jsonFields)
    res := make([]interface{}, numberOfJSONFields)
    fmt.Println(jsonFields)
    for fieldIndex, field := range jsonFields {
        for i := 0; i < numberOfFields; i++ {
            if structType.Field(i).Tag.Get("json") == field {
                valueField := structVal.Field(i)
                res[fieldIndex] = valueField.Addr().Interface()
            }
        }
    }

    return res
}

user := User{}
res := GetStructFieldPointers(&user, reflect.TypeOf(user), []string{"id", "name"}) 

我想知道如何将User{}作为参数&amp;用于反射.ValueOf&amp; reflect.TypeOf调用。

1 个答案:

答案 0 :(得分:3)

在这一行:structVal := reflect.ValueOf(&u).Elem()你正在获取接口的地址(你的func的参数),而不是接口的基础值的地址,然后你将指针传递给{{1因此ValueOf调用返回指针指向的“elem值”,即.Elem(),而不是结构。

如果您知道传入的值是结构而不是指针,那么您只需要:interface

如果指针传递给你的func,例如structVal := reflect.ValueOf(u),那么这就是你想要的:GetStructFieldPointers(&u, ...

但你也可以通过检查值的种类来处理这两种情况。

structVal := reflect.ValueOf(u).Elem()

https://play.golang.org/p/9F9LNnwEaH

<强>更新: 更好地查看代码...如果您希望能够获取结构域的地址,则需要将指针作为参数传递给结构,否则这些字段将是无法寻址的。

https://play.golang.org/p/RaA2rau3s-