如何从接口{}获取struct的成员的指针

Tim*_*nov 6 reflection pointers go

我想将struct的指针传递给期望接口{}的函数.然后获取(通过反射)指向struct的成员的指针,然后使用此指针修改它.我已经阅读了大量的问答并尝试了很多变化,但我仍然可以让它发挥作用.

让我们考虑以下示例:

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
Run Code Online (Sandbox Code Playgroud)

我认为这个问题很难理解究竟是什么做了反映包的Addr()Pointer()方法..

Cer*_*món 20

这是函数f的工作版本:

func f(i interface{}) {
  v := reflect.ValueOf(i).Elem().FieldByName("Id")
  ptr := v.Addr().Interface().(*int)
  *ptr = 100
}
Run Code Online (Sandbox Code Playgroud)

操场的例子

转换为整数指针如下:

  • vreflect.Value代表该int领域.
  • v.Addr()relfect.Value表示该int字段的指针.
  • v.Addr().Interface()是一个interface{}包含int指针.
  • v.Addr().Interface().(*int) 类型断言interface{}以一个*int

您可以直接设置字段而无需获取指针:

func f(i interface{}) {
  v := reflect.ValueOf(i).Elem().FieldByName("Id")
  v.SetInt(100)
}
Run Code Online (Sandbox Code Playgroud)

操场的例子

如果要将值传递给期望接口{}的内容(如db/sql Scan方法),则可以删除类型断言:

func f(i interface{}) {
  v := reflect.ValueOf(i).Elem().FieldByName("Id")
  scan(v.Addr().Interface())
}
Run Code Online (Sandbox Code Playgroud)

操场的例子

  • @TimurFayzrakhmanov我用表达式`v.Addr().接口().(*int)`的细分更新了答案. (2认同)