我的问题与此问题有关:
golang - Elem Vs Indirect in the reflect package
基本上它声称如果someX
是包含指针的reflect.Value
,则下面的表达式为真
reflect.Indirect(reflect.ValueOf(someX)) === reflect.ValueOf(someX).Elem()
如果是这种情况,那么为什么我的代码在最后一行崩溃?
package main
import (
"reflect"
"log"
)
type Person struct {
Name string
}
func main() {
newitem := reflect.New(reflect.ValueOf(Person{}).Type())
log.Println(reflect.TypeOf(newitem)) // shows reflect.Value
log.Println(newitem.Type().Kind()) // shows it is a ptr
log.Println(reflect.Indirect(reflect.ValueOf(newitem))) // this line does not cause panic
log.Println(reflect.ValueOf(newitem).Elem()) // this line causes panic
}
我一直很难理解Go中的反射包,很可能我误解了Go语言的一些基本方面,就像过去一周我一直在问的堆栈溢出问题所表达的那样。
让我们分解以下几行:
log.Println(reflect.ValueOf(newitem).Elem())
值newItem
是reflect.Value。表达式reflect.ValueOf(newItem)
返回包含reflect.Value
的reflect.Value
。因为包含的值不是指针或接口,所以对Elem()
的调用会引起恐慌。
以下行不会出现混乱,因为如果参数不是指针类型,reflect.Indirect将返回其参数。
log.Println(reflect.Indirect(reflect.ValueOf(newitem)))
问题是应用程序使用reflect.Values包装reflect.Values。直接使用reflect.Value,如下面的代码所示:
log.Println(reflect.Indirect(newitem))
log.Println(newitem.Elem())