如何通过反射从名称获取类型表示?

huangapple go评论88阅读模式
英文:

How to get Type representation from name via reflection?

问题

在Go语言中,可以使用反射库(reflection libraries)将类型的名称转换为其Type表示形式。用户可以通过创建该类型的变量并调用TypeOf函数来获取类型的表示形式。但是,是否有一种绕过这种方式,直接通过名称获取表示形式的方法呢?

英文:

Is there a way to use the reflection libraries in Go to go from the name of a type to its Type representation?

I've got a library where the user needs to provide Type representations for some code generation. I know it must be possible (in a sense) because they can just create a variable of that type and call the TypeOf function, but is there a way to circumvent this and just get representation from the name?

答案1

得分: 7

问题并不十分明确,可以有两种解释方式,其中一种的答案是否定的,不可能;而另一种的答案是肯定的,是可能的。

在运行时

如果类型名称以字符串形式提供,则在运行时是不可能的,因为未显式引用的类型可能不会编译到最终的可执行二进制文件中(因此在运行时显然变得无法访问,"未知")。有关详细信息,请参见 https://stackoverflow.com/questions/38875016/splitting-client-server-code/38875901#38875901。有关可能的解决方法,请参见 https://stackoverflow.com/questions/37384473/call-all-functions-with-special-prefix-or-suffix-in-golang/37384665#37384665

在"编码"时间

如果我们谈论的是"编码"时间(编写/生成源代码),那么可以在不创建/分配给定类型的变量并调用reflect.TypeOf()的情况下实现。

您可以从指向该类型的指针开始,并使用一个未分配的、具有类型的nil指针值,并且可以使用Type.Elem()从其reflect.Type描述符导航到指针的基本类型(或元素类型)的描述符。

代码示例如下:

t := reflect.TypeOf((*YourType)(nil)).Elem()

上述代码中的类型描述符t将与下面的t2相同:

var x YourType
t2 := reflect.TypeOf(x)

fmt.Println(t, t2)
fmt.Println(t == t2)

以上应用程序的输出结果(在Go Playground上尝试):

main.YourType main.YourType
true
英文:

The question is not quite explicit, it can be interpreted in 2 ways, to one of which the answer is no, not possible; and the other to which the answer is yes, it's possible.

At runtime

If the type name is provided as a string value, then at runtime it's not possible as types that are not referred to explicitly may not get compiled into the final executable binary (and thus obviously become unreachable, "unknown" at runtime). For details see https://stackoverflow.com/questions/38875016/splitting-client-server-code/38875901#38875901. For possible workarounds see https://stackoverflow.com/questions/37384473/call-all-functions-with-special-prefix-or-suffix-in-golang/37384665#37384665.

At "coding" time

If we're talking about "coding" time (source code writing / generating), then it's possible without creating / allocating a variable of the given type and calling reflect.TypeOf() and passing the variable.

You may start from the pointer to the type, and use a typed nil pointer value without allocation, and you can navigate from its reflect.Type descriptor to the descriptor of the base type (or element type) of the pointer using Type.Elem().

This is how it looks like:

t := reflect.TypeOf((*YourType)(nil)).Elem()

The type descriptor t above will be identical to t2 below:

var x YourType
t2 := reflect.TypeOf(x)

fmt.Println(t, t2)
fmt.Println(t == t2)

Output of the above application (try it on the Go Playground):

main.YourType main.YourType
true

huangapple
  • 本文由 发表于 2016年11月30日 11:28:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/40879748.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定