英文:
what does reflect.TypeOf((*error)(nil)).Elem()` mean?
问题
reflect.TypeOf((*error)(nil)).Elem()
是用于获取 error
类型的反射类型对象的方法。在这段代码中,reflect.TypeOf((*error)(nil))
返回的是 *error
类型的反射类型对象,而 .Elem()
方法则返回指针类型的基础类型,也就是 error
类型的反射类型对象。
在这段代码中,if mType.Out(0) != reflect.TypeOf((*error)(nil)).Elem()
的作用是判断方法的返回类型是否为 error
类型。通过使用 reflect.TypeOf((*error)(nil)).Elem()
,我们可以获取到 error
类型的反射类型对象,然后与方法的返回类型进行比较,以确定返回类型是否为 error
。
关于 (*error)(nil)
的使用,它表示一个空的 error
指针。在这里,我们需要使用指针类型来获取 error
的反射类型对象,因此使用 (*error)(nil)
来表示一个空的 error
指针。
你提到在编译代码时遇到了 type error is not an expression
的错误。这是因为 error
是一个接口类型,而不是一个具体的类型,所以不能直接使用 reflect.TypeOf(error)
来获取其反射类型对象。通过使用 (*error)(nil)
,我们可以创建一个空的 error
指针,然后使用 reflect.TypeOf()
来获取其反射类型对象。
希望这能解答你的疑惑!如果还有其他问题,请随时提问。
英文:
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)
}
}
what does reflect.TypeOf((*error)(nil)).Elem()
mean in this code? I know if mType.Out(0) != reflect.TypeOf((*error)(nil)).Elem()
is trying to determine if the method's return type is error not not. But for me, reflect.TypeOf((error)(nil))
intuitively will do the same, but unfortunately not. When I try to compile this code, it says type error is not an expression, what does it mean in this context? Does not reflect.Typeof()
accepts a argument of certain type? I found that (*error)(nil) is equivalent to *error = nil. I am confused with this expression.
答案1
得分: 7
reflect.TypeOf((*error)(nil)).Elem()
是一个表达式,用于获取接口类型 error
的 reflect.Type
类型描述符。使用 reflect.TypeOf(error(nil))
不能用于相同的目的(请阅读下面的原因)。
reflect.TypeOf((*error)(nil)).Elem()
通过使用类型为 *error
的有类型 nil
指针值,将其传递给 reflect.TypeOf()
来实现其目标,以获取类型为 *error
的 reflect.Type
描述符,并使用 Type.Elem()
获取 *error
的元素(基本)类型的类型描述符,即 error
。
reflect.TypeOf()
期望一个 interface{}
值:
func TypeOf(i interface{}) Type
基本上,无论您传递给 reflect.TypeOf()
的值是什么,如果它还不是一个接口值,它将被隐式地包装在一个 interface{}
中。如果传递的值已经是一个接口值,那么存储在其中的具体值将作为 interface{}
传递。
因此,如果您尝试将一个 error
值传递给它,由于 error
是一个接口类型,存储在其中的具体值将被“重新打包”为一个 interface{}
值。接口类型 error
将不会被保留/传递!
如果您传递一个类型为 error
的 nil
值,例如 error(nil)
,由于接口值本身是 nil
,它不包含具体值和类型,将传递一个 nil
的 interface{}
值,这将导致返回 nil
的 reflect.Type
。引用自 reflect.TypeOf()
:
> TypeOf 返回表示 i 的动态类型的反射类型。如果 i 是一个 nil 接口值,则 TypeOf 返回 nil。
如果您传递一个类型为 *error
的值(可能是一个 nil
指针),它不是一个接口值,而是一个指针值(指向接口的指针)。因此,它将被包装在一个 interface{}
值中,并且存储在其中的具体值将是 *error
类型。使用 Type.Elem()
您可以访问指向的类型,即 error
。
这是使用指向接口的指针的少数几种情况之一,事实上是不可避免的。
参考相关问题:
英文:
TL;DR; reflect.TypeOf((*error)(nil)).Elem()
is an expression used to obtain the reflect.Type
type descriptor of the interface type error
. Using reflect.TypeOf(error(nil))
cannot be used for the same purpose (read the why below).
reflect.TypeOf((*error)(nil)).Elem()
achieves its goal by using a typed nil
pointer value of type *error
, passing it to reflect.TypeOf()
to get the reflect.Type
descriptor of the type *error
, and uses Type.Elem()
to get the type descriptor of the element (base) type of *error
, which is error
.
reflect.TypeOf()
expects an interface{}
value:
func TypeOf(i interface{}) Type
Basically whatever value you pass to reflect.TypeOf()
, if it's not already an interface value, it will be wrapped in an interface{}
implicitly. If the passed value is already an interface value, then the concrete value stored in it will be passed as interface{}
.
So if you try to pass an error
value to it, since error
is an interface type, the concrete value stored in it will be "repacked" into an interface{}
value. The interface type error
will not be retained / transferred!
If you pass a nil
value of type error
, e.g. error(nil)
, since the interface value itself is nil
, it contains no concrete value and type, a nil
interface{}
value will be passed, that will result in nil
reflect.Type
returned. Quoting from reflect.TypeOf()
:
> TypeOf returns the reflection Type that represents the dynamic type of i. If i is a nil interface value, TypeOf returns nil.
If you pass a value of type *error
(which may be a nil
pointer), it's not an interface value, it's a pointer value (a pointer to interface). So it will be wrapped in an interface{}
value, and the concrete value stored in it will be of type *error
. Using Type.Elem()
you can access the pointed type, that is error
.
This is one of the rare cases when using a pointer to interface makes sense, and in fact inevitable.
See related questions:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论