为什么反映错误类型的名称(或包路径)会导致 Go 出现 panic?
Why does reflecting the name (or package path) of the error type cause a panic in Go?
Golang中使用反射获取error
类型的名称或包路径导致程序panic(withpanic: runtime error: invalid memory address or nil pointer dereference
)
这种行为的原因是什么? (对其他内置类型执行相同的操作 returns 类型名称和包路径的空字符串。)
我对语言的设计很感兴趣 - 我不明白为什么 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
}
error
没什么特别的,只是它是一个接口。
reflect.TypeOf
接受一个 interface{}
类型的参数。如果您使用非接口值调用它,该值及其类型将包装在 interface{}
中。如果您使用接口值调用它,则基础值和类型将从接口中提取出来,并包装在一个新的 interface{}
值中。如果你用一个空接口调用它(就像你在这里做的那样,因为 error
是一个接口并且它是零初始化的),那么就没有基础值和类型,并且 reflect.TypeOf
的参数是一个新的 nil interface{}
值。在这种情况下,reflect.TypeOf
被定义为 return nil
,导致您出现零问题。
我认为您的困惑是接口值的 TypeOf
是其基础值的类型,它永远不是接口。您希望接口值的 TypeOf
是接口类型本身,但这不是它的工作方式。
Golang中使用反射获取error
类型的名称或包路径导致程序panic(withpanic: runtime error: invalid memory address or nil pointer dereference
)
这种行为的原因是什么? (对其他内置类型执行相同的操作 returns 类型名称和包路径的空字符串。)
我对语言的设计很感兴趣 - 我不明白为什么 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
}
error
没什么特别的,只是它是一个接口。
reflect.TypeOf
接受一个 interface{}
类型的参数。如果您使用非接口值调用它,该值及其类型将包装在 interface{}
中。如果您使用接口值调用它,则基础值和类型将从接口中提取出来,并包装在一个新的 interface{}
值中。如果你用一个空接口调用它(就像你在这里做的那样,因为 error
是一个接口并且它是零初始化的),那么就没有基础值和类型,并且 reflect.TypeOf
的参数是一个新的 nil interface{}
值。在这种情况下,reflect.TypeOf
被定义为 return nil
,导致您出现零问题。
我认为您的困惑是接口值的 TypeOf
是其基础值的类型,它永远不是接口。您希望接口值的 TypeOf
是接口类型本身,但这不是它的工作方式。