无法反映到不返回指针,编译器恐慌转换?

时间:2016-05-28 18:00:50

标签: pointers reflection go interface

围绕这样的代码写的代码引起了一个问题:

func CreateNewItemOfType(returnType reflect.Type) (interface {}) {
    return reflect.New(returnType).Interface();

}

...如何实际返回returnType的结构而不是结构的指针,reflect在这里创建?编译器在运行时构建这个很好但是恐慌,但是在这里返回调用前不会接受星号,以便实际返回结构而不是指针。

1 个答案:

答案 0 :(得分:2)

reflect.New()创建指定类型的新值,并将指针reflect.Value描述符返回到该值。您可以使用Value.Elem()来"导航"从指针到包含在reflect.Value中的指向值。然后,您可以调用Value.Interface()将值(struct)作为interface{}值。

如果您需要具体类型的值,可以使用type assertion来提取"提取"包含在interface{}值中的值。

func CreateNewItemOfType(returnType reflect.Type) interface{} {
    return reflect.New(returnType).Elem().Interface()
}

测试它:

type Point struct {
    X, Y int
}

t := reflect.TypeOf(Point{})

i := CreateNewItemOfType(t) // i is of type interface{}
fmt.Printf("%T %+v\n", i, i)

pt := i.(Point) // pt is of type Point
fmt.Printf("%T %+v\n", pt, pt)

输出(在 Go Playground 上试试):

main.Point {X:0 Y:0}
main.Point {X:0 Y:0}

注意:

如果未使用Value.Elem(),也可以获取非指针结构值。为此,您需要键入 - 断言指针值(类型为*Point),然后您可以取消引用指针以获取非指针。

见这个例子:

t := reflect.TypeOf(Point{})
pi := reflect.New(t).Interface() // pi is of type interface{}
fmt.Printf("%T %+v\n", pi, pi)

ppt := pi.(*Point) // pt is of type *Point
fmt.Printf("%T %+v\n", ppt, ppt)

i2 := *ppt // i2 is of type Point
fmt.Printf("%T %+v\n", i2, i2)

输出:

*main.Point &{X:0 Y:0}
*main.Point &{X:0 Y:0}
main.Point {X:0 Y:0}