我想将一个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调用。
答案 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
<强>更新强>: 更好地查看代码...如果您希望能够获取结构域的地址,则需要将指针作为参数传递给结构,否则这些字段将是无法寻址的。