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)
}
}
Run Code Online (Sandbox Code Playgroud)
reflect.TypeOf((*error)(nil)).Elem()这段代码是什么意思?我知道if mType.Out(0) != reflect.TypeOf((*error)(nil)).Elem()正在尝试确定方法的返回类型是否错误。但对我来说,reflect.TypeOf((error)(nil))直觉上也会做同样的事情,但不幸的是不是。当我尝试编译此代码时,它说类型错误不是表达式,这在这种情况下意味着什么?不reflect.Typeof()接受某种类型的参数?我发现 (*error)(nil) 相当于 *error = nil。我对这个表达感到困惑。
TL;博士; reflect.TypeOf((*error)(nil)).Elem()是用于获取reflect.Type接口类型的类型描述符的表达式error。使用reflect.TypeOf(error(nil)) 不能用于相同的目的(请阅读下面的原因)。
reflect.TypeOf((*error)(nil)).Elem()通过使用niltype 的类型化指针值*error,将其传递给 来reflect.TypeOf()获取reflect.Type类型的描述符*error,并使用Type.Elem()来获取 的元素(基)类型的类型描述符*error,即 ,从而实现其目标error。
reflect.TypeOf()期望一个interface{}值:
func TypeOf(i interface{}) Type
Run Code Online (Sandbox Code Playgroud)
基本上,无论您传递给 的值是什么reflect.TypeOf(),如果它还不是接口值,它将被interface{}隐式包装在一个接口值中。如果传递的值已经是一个接口值,那么存储在其中的具体值将被传递为interface{}。
error因此,如果您尝试向它传递一个值,由于error它是一个接口类型,因此存储在其中的具体值将被“重新打包”为一个interface{}值。接口类型error不会被保留/转移!
如果你传递一个nil类型的值error,例如error(nil),由于接口值本身是nil,它不包含具体的值和类型,nil interface{}将传递一个值,这将导致nil reflect.Type返回。引用自reflect.TypeOf():
TypeOf 返回表示 i 的动态类型的反射 Type。如果 i 是 nil 接口值,则 TypeOf 返回 nil。
如果传递类型的值*error(可能是nil指针),那么它不是接口值,而是指针值(指向接口的指针)。因此它将被包装在一个interface{}值中,并且存储在其中的具体值将是类型*error。使用Type.Elem()可以访问指向类型,即error.
这是使用接口指针有意义且实际上不可避免的罕见情况之一。
查看相关问题:
go中的reflect.ValueOf()和Value.Elem()有什么区别?
| 归档时间: |
|
| 查看次数: |
1477 次 |
| 最近记录: |