在 Go 中使用反射来获取结构的名称 [英] using reflection in Go to get the name of a struct
问题描述
我发现这个问题的答案很好:
我尝试了答案并尝试以相同的方式获取结构的名称:
包主进口 (fmt"反映")类型 Ab 结构 {}func getType(myvar interface{}) string {返回reflect.TypeOf(myvar).Name()}功能主(){fmt.Println("你好,游乐场")tst := "字符串"tst2 := 10tst3 := 1.2tst4 := 新的(Ab)fmt.Println(getType(tst))fmt.Println(getType(tst2))fmt.Println(getType(tst3))fmt.Println(getType(tst4))}
去游乐场:http://play.golang.org/p/tD8mygvETH>
但输出是:
你好,游乐场细绳整数浮动64程序退出.
预期输出为:
你好,游乐场细绳整数浮动64抗体程序退出.
我试图通过阅读文档来弄清楚,但没有找到相关问题.所以,对于这个非常普遍的问题,抱歉,但是:
是什么原因,reflect.TypeOf().Name()
不适用于(这个)结构?
在您的示例中,您传递的是指针类型 (*Ab
) 的值,而不是结构类型.
坚持Type.Name()
如果不是指针,Type.Name()
将正确返回Ab
.在指针的情况下,如果您仍然想要结构的名称,则可以使用 Type.Elem()
来获取元素的类型:
func getType(myvar interface{}) string {如果 t :=reflect.TypeOf(myvar);t.Kind() == 反射.Ptr {返回 "*" + t.Elem().Name()} 别的 {返回 t.Name()}}
测试:
tst4 := Ab{}tst5 := 新的(Ab)fmt.Println(getType(tst4))fmt.Println(getType(tst5))
输出(在 Go Playground 上尝试修改后的示例):
抗体*抗体
注意:
请注意,由于 Type.Name()
不解析指针,如果传递的值是指向指针的指针,则它不起作用,例如**Ab
,虽然 Type.String()
自动解析指针,但在这种情况下也能工作.
我们也可以轻松地使 getType()
函数与 **Ab
一起工作(或任何深度的指针):
func getType(myvar interface{}) (res string) {t :=reflect.TypeOf(myvar)对于 t.Kind() ==reflect.Ptr {t = t.Elem()资源 += "*"}返回 res + t.Name()}
用值调用它:
tst4 := Ab{}tst5 := 新的(Ab)tst6 := &tst5//**Ab 的类型tst7 := &tst6//***Ab 的类型
输出(在 Go Playground 上试试):
抗体*抗体**抗体***抗体
使用Type.String()
一种更简单更好的方法是使用 Type.String()
而不是 Type.Name()
,后者会自动处理指针并包含包名称.例如:
func getType(myvar interface{}) string {返回reflect.TypeOf(myvar).String()}
对于修改后的例子,它输出:
字符串整数浮动64主要抗体*主抗体
在 Go Playground 上试试这个变体.
I found this question with this great answers:
How to find a type of a object in Golang?
I played around with the answer and tried to get the name of a struct in the same way:
package main
import (
"fmt"
"reflect"
)
type Ab struct {
}
func getType(myvar interface{}) string {
return reflect.TypeOf(myvar).Name()
}
func main() {
fmt.Println("Hello, playground")
tst := "string"
tst2 := 10
tst3 := 1.2
tst4 := new(Ab)
fmt.Println(getType(tst))
fmt.Println(getType(tst2))
fmt.Println(getType(tst3))
fmt.Println(getType(tst4))
}
Go playground: http://play.golang.org/p/tD8mygvETH
But the output is:
Hello, playground
string
int
float64
Program exited.
Expected output would be:
Hello, playground
string
int
float64
Ab
Program exited.
I tried to figure out by reading the documentation but didn't find the issue about that. So, sorry for the very general question, but:
What's the reason, reflect.TypeOf().Name()
does not work with (this) struct(s)?
In your example you pass a value of pointer type (*Ab
), not a struct type.
Sticking to Type.Name()
If it is not a pointer, Type.Name()
will properly return Ab
. In case of pointer if you still want the struct's name, you can use Type.Elem()
to get the element's type:
func getType(myvar interface{}) string {
if t := reflect.TypeOf(myvar); t.Kind() == reflect.Ptr {
return "*" + t.Elem().Name()
} else {
return t.Name()
}
}
Testing it:
tst4 := Ab{}
tst5 := new(Ab)
fmt.Println(getType(tst4))
fmt.Println(getType(tst5))
Output (try your modified example on the Go Playground):
Ab
*Ab
Note:
Note that as Type.Name()
does not resolve pointers, it would not work if the value passed is a pointer to pointer, e.g. **Ab
, while as Type.String()
automatically resolves pointers, would work in this case too.
We can easily make our getType()
function to work with **Ab
too (or with any depth of pointers):
func getType(myvar interface{}) (res string) {
t := reflect.TypeOf(myvar)
for t.Kind() == reflect.Ptr {
t = t.Elem()
res += "*"
}
return res + t.Name()
}
Calling it with values:
tst4 := Ab{}
tst5 := new(Ab)
tst6 := &tst5 // type of **Ab
tst7 := &tst6 // type of ***Ab
Output (try it on the Go Playground):
Ab
*Ab
**Ab
***Ab
Using Type.String()
A simpler and better approach would be to use Type.String()
instead of Type.Name()
which automatically handles pointers and also includes package name. E.g.:
func getType(myvar interface{}) string {
return reflect.TypeOf(myvar).String()
}
For the modified example it outputs:
string
int
float64
main.Ab
*main.Ab
Try this variant on the Go Playground.
这篇关于在 Go 中使用反射来获取结构的名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!