reflect.New返回<nil>而不是初始化的struct

时间:2017-03-28 14:35:48

标签: pointers go reflection struct

我正在使用反射来构建我正在构建的库,但我对reflect.New有些不了解。

type A struct {
    A int
    B string
}

func main() {

    real := new(A)
    reflected := reflect.New(reflect.TypeOf(real)).Elem().Interface()
    fmt.Println(real)
    fmt.Println(reflected)
}

给出:

$ go run *go
&{0 }
<nil>

reflect.New是否也应该返回&{0 }? (Runnable Version

最终,我希望能够遍历反射结构的字段(reflected.NumField()给出reflected.NumField undefined (type interface {} is interface with no methods))并使用SetIntSetString等等。< / p>

谢谢,

1 个答案:

答案 0 :(得分:5)

您在创建real变量时使用了内置new()函数,该变量返回指针! real的类型为*A,而不是A!这是混乱的根源。

reflect.New()返回指向给定类型的(归零)值的指针(包含在reflect.Value中)。如果您传递了A类型,则会返回已初始化/归零的包裹*AA。如果您传递类型*A,则会返回一个包装**A*A初始化(归零),任何指针类型的零值为nil

您基本上要求reflect.New()创建指针类型的新值(*A),并且 - 如上所述 - 其零值为nil

您必须传递A类型(而不是类型*A)。它的工作原理如下(在Go Playground上试试):

real := new(A)
reflected := reflect.New(reflect.TypeOf(real).Elem()).Elem().Interface()
fmt.Println(real)
fmt.Println(reflected)

或者像这样(Go Playground):

real := A{}
reflected := reflect.New(reflect.TypeOf(real)).Elem().Interface()
fmt.Println(real)
fmt.Println(reflected)