【发布时间】:2020-04-14 21:48:36
【问题描述】:
在 Golang 中使用反射获取 error 类型的名称或包路径会导致程序崩溃(使用 panic: runtime error: invalid memory address or nil pointer dereference)。
这种行为的原因是什么? (对其他内置类型执行相同的操作会返回类型名称和包路径的空字符串。)
我对语言的设计很感兴趣——我不明白为什么 error 类型的行为与其他内置类型不同。
例如:
package main
import (
"fmt"
"reflect"
)
func main() {
var str string
strType := reflect.TypeOf(str)
fmt.Println(strType.Name()) // OK
fmt.Println(strType.PkgPath()) // OK
var err error
errType := reflect.TypeOf(err)
fmt.Println(errType.Name()) // panics
fmt.Println(errType.PkgPath()) // also panics
}
【问题讨论】:
-
如果 Go 像其他面向对象的语言一样工作,
var err error只是为错误interface声明一个 容器 而不是实际实例化的对象。所以errType := reflect.TypeOf(err)返回null,这听起来对我来说是正确的。 -
err是一个接口,当你声明它而不初始化时它是nil。正因为如此,reflect.TypeOf(err)是 nil,当你得到它的名字时,它会恐慌。 -
问题中的代码获取
err的值的reflect.Type。该值为 nil 并且没有类型,因此会出现恐慌。使用reflect.TypeOf(&err).Elem()获取变量err的reflect.Type。注意变量的类型和值的类型之间的区别。试试这个:play.golang.org/p/pFtNBXEyz8w -
变量
err被初始化为零值。表达式&err计算为变量的地址。 -
@RobertHarvey 所有类型都有一个zero value,包括接口。
标签: go go-reflect