为了账号安全,请及时绑定邮箱和手机立即绑定

reflect.TypeOf((*error)(nil)).Elem()` 是什么意思?

reflect.TypeOf((*error)(nil)).Elem()` 是什么意思?

Go
杨__羊羊 2023-03-07 11:04:25
func (s *service) registerMethods() {    s.method = make(map[string]*methodType)    for i := 0; i < s.typ.NumMethod(); i++ {        method := s.typ.Method(i)        mType := method.Type        if mType.NumIn() != 3 || mType.NumOut() != 1 {            continue        }        if mType.Out(0) != reflect.TypeOf((*error)(nil)).Elem() {            continue        }        argType, replyType := mType.In(1), mType.In(2)        if !isExportedOrBuiltinType(argType) || !isExportedOrBuiltinType(replyType) {            continue        }        s.method[method.Name] = &methodType{            method:    method,            ArgType:   argType,            ReplyType: replyType,        }        log.Printf("rpc server: register %s.%s\n", s.name, method.Name)    }}reflect.TypeOf((*error)(nil)).Elem()这段代码是什么意思?我知道if mType.Out(0) != reflect.TypeOf((*error)(nil)).Elem()正在尝试确定方法的返回类型是否为错误。但对我来说,reflect.TypeOf((error)(nil))直觉上会做同样的事情,但不幸的是不会。当我尝试编译这段代码时,它说 type error is not an expression,在这种情况下它是什么意思?不reflect.Typeof()接受某种类型的参数?我发现 (*error)(nil) 等同于 *error = nil。在上面的上下文中,我对这个表达感到困惑。
查看完整描述

1 回答

?
holdtom

TA贡献1805条经验 获得超10个赞

长话短说;博士; reflect.TypeOf((*error)(nil)).Elem()是一个表达式,用于获取reflect.Type接口类型的类型描述符error。usingreflect.TypeOf(error(nil)) 不能用于相同的目的(阅读下面的原因)。


reflect.TypeOf((*error)(nil)).Elem()通过使用niltype 的类型化指针值实现其目标*error,将其传递给reflect.TypeOf()以获取reflect.Typetype 的描述符*error,并使用Type.Elem()获取 的元素(基)类型的类型描述符*error,即error

reflect.TypeOf()期望一个interface{}值:

func TypeOf(i interface{}) Type

基本上无论你传递给什么值reflect.TypeOf(),如果它还不是一个接口值,它都会被interface{}隐式地包装起来。如果传递的值已经是一个接口值,那么存储在其中的具体值将作为interface{}.

因此,如果您尝试向它传递一个error值,因为它error是一个接口类型,存储在其中的具体值将被“重新打包”为一个interface{}值。接口类型error不会被保留/转移!

如果你传递一个nil类型的值error,例如error(nil),因为接口值本身是nil,它不包含具体的值和类型,一个nil interface{}值将被传递,这将导致nil reflect.Type返回。引用自reflect.TypeOf()

TypeOf 返回表示 i 的动态类型的反射类型。如果 i 是 nil 接口值,则 TypeOf 返回 nil。

如果你传递一个类型的值*error(可能是一个nil指针),它不是一个接口值,它是一个指针值(一个指向接口的指针)。所以它将被包裹在一个interface{}值中,存储在其中的具体值将是 type *error。使用Type.Elem()您可以访问指向的类型,即error.

这是使用指向接口的指针有意义且实际上不可避免的罕见情况之一。


查看完整回答
反对 回复 2023-03-07
  • 1 回答
  • 0 关注
  • 94 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信