pointers - 无法反射(reflect)不返回指针,编译器在转换时出现 panic ?

标签 pointers reflection go interface

围绕这样的东西编写的代码导致了一个问题:

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

}

... 如何实际返回 returnType 的结构而不是指向结构的指针,如 reflect 在这里创建的那样?编译器可以很好地构建它,但在运行时会出现 panic ,但不会在此处的 return 调用前接受星号,以便实际返回结构而不是指针。

最佳答案

reflect.New()创建指定类型的新值,并返回 reflect.Value指向该值的指针的描述符。您可以使用 Value.Elem()从指针“导航”到包裹在 reflect.Value 中的指向值。然后你可以调用Value.Interface()获取作为 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}

关于pointers - 无法反射(reflect)不返回指针,编译器在转换时出现 panic ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37502226/

相关文章:

c++ - 使用指针在 C++ 中缩小类型转换

pointers - 是否可以匹配 Rust 中的 NULL 指针?

c# - 如何更改通过反射 C# 获取的属性值

go - 从伪终端获取先前的输入

Golang 类型断言

c++ - 通过指针传递与通过引用传递

c# - 在没有类型拆箱的情况下调用具有特定参数的方法

c# - 在 C# 中执行操作的 MethodInfo

go - 将服务帐户 key 文件传递给 bigquery 客户端

c - 在 C 中使用指针对字符串数组进行排序