In your example, you are passing a pointer type value ( *Ab ), not a structure type.
Type.Name()
If this is not a pointer, Type.Name() will correctly return Ab . In the case of a pointer, if you still want the name of the structure, you can use Type.Elem() to get the type of the element:
func getType(myvar interface{}) string { if t := reflect.TypeOf(myvar); t.Kind() == reflect.Ptr { return "*" + t.Elem().Name() } else { return t.Name() } }
Testing:
tst4 := Ab{} tst5 := new(Ab) fmt.Println(getType(tst4)) fmt.Println(getType(tst5))
Conclusion (try your modified Go Playground example):
Ab *Ab
Note:
Note that since Type.Name() does not allow pointers, this will not work if the passed value is a pointer to a pointer, for example. **Ab , while Type.String() automatically resolves pointers, will work in this case Type.String() .
We can easily get our getType() function to work with **Ab too (or with any pointer depth):
func getType(myvar interface{}) (res string) { t := reflect.TypeOf(myvar) for t.Kind() == reflect.Ptr { t = t.Elem() res += "*" } return res + t.Name() }
Call with values:
tst4 := Ab{} tst5 := new(Ab) tst6 := &tst5 // type of **Ab tst7 := &tst6 // type of ***Ab
Exit (try 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 processes pointers and also includes the package name. For instance:.
func getType(myvar interface{}) string { return reflect.TypeOf(myvar).String() }
For a modified example, it outputs:
string int float64 main.Ab *main.Ab
Try this option on the Go Playground .