如何通过反射初始化结构指针

lim

我的目标是获取一个nil指向结构指针(但可以是任何类型),以形式传递interface{},并在其位置初始化一个结构。

我的测试代码(操场链接)是:

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

松饼上衣:

试试这个:

var x *Foo
var y interface{} = x
fmt.Printf("Before: %#v\n", y)
fmt.Printf("Goal: %#v\n", interface{}(&Foo{}))

// Must take address of y to set it. Dereference with Elem() to get value for y
rv := reflect.ValueOf(&y).Elem()

// Interface element type is *main.Foo, dereference with Elem() to get main.Foo
t := rv.Elem().Type().Elem()
rv.Set(reflect.New(t))
fmt.Printf("After: %#v\n", y)

游乐场的例子

您还可以分配y而不是通过反射进行设置:

var x *Foo
var y interface{} = x
fmt.Printf("Before: %#v\n", y)
fmt.Printf("Goal: %#v\n", interface{}(&Foo{}))
rv := reflect.ValueOf(y)
t := rv.Type().Elem()
y = reflect.New(t).Interface()
fmt.Printf("After: %#v\n", y)

游乐场的例子

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章