如何从接口{}获取结构成员的指针
How get pointer of struct's member from interface{}
我想将结构指针传递给需要接口{}的函数。然后(通过反射)获取指向结构成员的指针,然后使用该指针修改它。我已经阅读了很多问答并尝试了很多变体,但我仍然可以让它工作。
让我们考虑下面的例子:
type Robot struct {
Id int
}
f := func(i interface {}) {
v := reflect.ValueOf(i).Elem().FieldByName("Id")
ptr := v.Addr().Pointer()
*ptr = 100
//^ it needs to me for functions expecting the pointer: Scan(&pointerToValue)
}
robot := &Robot{}
f(robot)
println(robot.Id) //I want to get here 100
我认为问题在于对反射包的 Addr() 和 Pointer() 方法的实际作用知之甚少..
这是函数 f 的工作版本:
func f(i interface{}) {
v := reflect.ValueOf(i).Elem().FieldByName("Id")
ptr := v.Addr().Interface().(*int)
*ptr = 100
}
整型指针转换如下:
v
是代表 int
字段的 reflect.Value
。
v.Addr()
是一个 relfect.Value
,表示指向 int
字段的指针。
v.Addr().Interface()
是一个包含 int
指针的 interface{}
。
v.Addr().Interface().(*int)
type asserts interface{}
一个 *int
无需获取指针即可直接设置字段:
func f(i interface{}) {
v := reflect.ValueOf(i).Elem().FieldByName("Id")
v.SetInt(100)
}
如果您将值传递给需要接口{}的东西(例如 db/sql Scan 方法),那么您可以删除类型断言:
func f(i interface{}) {
v := reflect.ValueOf(i).Elem().FieldByName("Id")
scan(v.Addr().Interface())
}
我想将结构指针传递给需要接口{}的函数。然后(通过反射)获取指向结构成员的指针,然后使用该指针修改它。我已经阅读了很多问答并尝试了很多变体,但我仍然可以让它工作。
让我们考虑下面的例子:
type Robot struct {
Id int
}
f := func(i interface {}) {
v := reflect.ValueOf(i).Elem().FieldByName("Id")
ptr := v.Addr().Pointer()
*ptr = 100
//^ it needs to me for functions expecting the pointer: Scan(&pointerToValue)
}
robot := &Robot{}
f(robot)
println(robot.Id) //I want to get here 100
我认为问题在于对反射包的 Addr() 和 Pointer() 方法的实际作用知之甚少..
这是函数 f 的工作版本:
func f(i interface{}) {
v := reflect.ValueOf(i).Elem().FieldByName("Id")
ptr := v.Addr().Interface().(*int)
*ptr = 100
}
整型指针转换如下:
v
是代表int
字段的reflect.Value
。v.Addr()
是一个relfect.Value
,表示指向int
字段的指针。v.Addr().Interface()
是一个包含int
指针的interface{}
。v.Addr().Interface().(*int)
type assertsinterface{}
一个*int
无需获取指针即可直接设置字段:
func f(i interface{}) {
v := reflect.ValueOf(i).Elem().FieldByName("Id")
v.SetInt(100)
}
如果您将值传递给需要接口{}的东西(例如 db/sql Scan 方法),那么您可以删除类型断言:
func f(i interface{}) {
v := reflect.ValueOf(i).Elem().FieldByName("Id")
scan(v.Addr().Interface())
}