【发布时间】:2017-07-13 00:33:14
【问题描述】:
我的目标是获取一个指向结构(但可以是任何类型)的nil 指针,作为interface{} 传递,并在其位置初始化一个结构。
我的测试代码(playground link)是:
package main
import (
"fmt"
"reflect"
)
type Foo struct {
Foo string
}
func main() {
var x *Foo
var y interface{} = x
fmt.Printf("Before: %#v\n", y)
fmt.Printf("Goal: %#v\n", interface{}(&Foo{}))
rv := reflect.ValueOf(y)
rv.Set(reflect.New(rv.Type().Elem()))
fmt.Printf("After: %#v\n", y)
}
我希望代码是自记录的。但目标本质上是将y 转换为指向Foo 的未初始化指针((*main.Foo)(nil)) 转换为指向Foo: &main.Foo{Foo:""} 的已初始化(零值)实例的指针。但我收到reflect.Value.Set using unaddressable value。我不明白为什么我试图设置的值是不可寻址的。我花了一天时间阅读标准库 JSON unmarshaler 的源代码和其他 SO 帖子,但仍然明显忽略了一些东西。
如果我剥掉外面的interface{}:
rv := reflect.ValueOf(y).Elem() // Remove the outer interface{}
rv.Set(reflect.New(rv.Type().Elem()))
错误变为reflect: call of reflect.Value.Type on zero Value。
【问题讨论】:
-
使用循环意味着可能有任意多个层,但只有三层:变量的接口类型、指向值的指针和值本身。
-
@Adrian:在生产中,可能有任意数量的层。但在这里,显然没有。我已经删除了循环。
-
如何得到任意数量的层?
-
@Adrian:
SomeUnmarshalWrapper(&result)后跟func SomeUnmarshalWrapper(i interface{}) { json.Unmarshal(&i) ...或类似的。
标签: go reflection