英文:
Better way to get the reflect.Type of an interface in Go
问题
有没有比在Go中使用reflect.TypeOf((*someInterface)(nil)).Elem()
更好的方法来获取接口的reflect.Type
?它确实能够工作,但每次我滚动到它时都让我感到不舒服。
英文:
Is there an better way to get the reflect.Type
of an interface in Go than reflect.TypeOf((*someInterface)(nil)).Elem()
?
It works, but it makes me cringe every time I scroll past it.
答案1
得分: 3
很不幸,没有。虽然它看起来很丑,但它确实表达了获取所需的reflect.Type
所需的最小信息量。通常,这些信息会在文件顶部的var()
块中包含,其中包含所有这些必要的类型,以便在程序初始化时计算它们,并且不会在每次函数需要该值时产生TypeOf
查找开销。
这种习惯用法在标准库中被广泛使用,例如:
html/template/content.go: errorType = reflect.TypeOf((*error)(nil)).Elem()
这种冗长的构造方式的原因在于reflect.TypeOf
是一个库的一部分,而不是内置的,因此实际上必须接受一个值。
在某些语言中,类型的名称是一个可以用作表达式的标识符。但在Go中不是这样的。有效的表达式可以在规范中找到。如果类型的名称也可以用作reflect.Type
,那么它将为方法表达式引入歧义,因为reflect.Type
有自己的方法(实际上,它是一个接口)。这也会将语言规范与标准库耦合在一起,从而降低了两者的灵活性。
英文:
Unfortunately, there is not. While it might look ugly, it is indeed expressing the minimal amount of information needed to get the reflect.Type
that you require. These are usually included at the top of the file in a var()
block with all such necessary types so that they are computed at program init and don't incur the TypeOf
lookup penalty every time a function needs the value.
This idiom is used throughout the standard library, for instance:
html/template/content.go: errorType = reflect.TypeOf((*error)(nil)).Elem()
The reason for this verbose construction stems from the fact that reflect.TypeOf
is part of a library and not a built-in, and thus must actually take a value.
In some languages, the name of a type is an identifier that can be used as an expression. This is not the case in Go. The valid expressions can be found in the spec. If the name of a type were also usable as a reflect.Type
, it would introduce an ambiguity for method expressions because reflect.Type
has its own methods (in fact, it's an interface). It would also couple the language spec with the standard library, which reduces the flexibility of both.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论