为什么反映错误类型的名称(或包路径)会导致 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
}

去游乐场:https://play.golang.org/p/JBMhMkjGPEV

error 没什么特别的,只是它是一个接口。

reflect.TypeOf 接受一个 interface{} 类型的参数。如果您使用非接口值调用它,该值及其类型将包装在 interface{} 中。如果您使用接口值调用它,则基础值和类型将从接口中提取出来,并包装在一个新的 interface{} 值中。如果你用一个空接口调用它(就像你在这里做的那样,因为 error 是一个接口并且它是零初始化的),那么就没有基础值和类型,并且 reflect.TypeOf 的参数是一个新的 nil interface{} 值。在这种情况下,reflect.TypeOf 被定义为 return nil,导致您出现零问题。

我认为您的困惑是接口值的 TypeOf 是其基础值的类型,它永远不是接口。您希望接口值的 TypeOf 是接口类型本身,但这不是它的工作方式。