错误:类型CustomStruct不是表达式。
type CustomStruct struct {
}
func getTypeName(t interface{}) string {
rt := reflect.TypeOf(t).Elem()
return rt.Name()
}
getTypeName(CustomStruct)
如何在没有类型实例的情况下将结构类型传递给函数?
这将起作用
getTypeName((*CustomStruct)(nil))
但是我想知道是否还有更简单的版本。
答案 0 :(得分:7)
不能。您只能传递一个值,并且CustomStruct
不是值,而是类型。使用类型标识符是编译时错误。
通常,当要传递“类型”时,您传递描述该类型的reflect.Type
值。这是您在getTypeName()
内“创建”的内容,但是getTypeName()
几乎没什么可做的:
func getTypeName(t reflect.Type) string {
return t.Name()
}
// Calling it:
getTypeName(reflect.TypeOf(CustomStruct{}))
(也不要忘记,对于诸如[]int
之类的匿名类型,它返回一个空字符串。)
另一种方法是像您一样传递“类型化的” nil
指针值,但是同样,您也可以使用类型化的nil
值来创建reflect.Type
,而不创建相关类型的值,例如:
t := reflect.TypeOf((*CustomStruct)(nil)).Elem()
fmt.Println(t.Name()) // Prints CustomStruct
答案 1 :(得分:1)
让我们复活这个!
Go 的泛型提案获得批准,并且最终会到来。当这个问题第一次被问到时,这可能更有意义,但是对于现在想要实现泛型模式的任何人来说,我想我已经有了一个不错的 API。
目前,您不能与抽象类型交互,但您可以与抽象类型上的方法交互,并且反射允许您检查函数签名。对于方法,第 0 个是接收者。
type Example struct {int}
type Generic struct{reflect.Type}
func (p Example) Type() {}
func Reflect(generic interface{}) Generic {
real := reflect.TypeOf(generic)
if real.Kind() != reflect.Func || real.NumIn() < 1 {
panic("reflect.Type.In(n) panics if not a func and if n out of bounds")
}
return Generic{real.In(0)}
}
func (g Generic) Make() interface{} {
return reflect.Zero(g.Type).Interface()
}
func main() {
tOfp := Reflect(Example.Type)
fmt.Printf("Name of the type: %v\n", tOfp.Name())
fmt.Printf("Real (initial)value: %v\n", tOfp.Make())
}
一些快速笔记:
如果您不知道,真正的泛型将在 Go 1.18 中出现。我上面的例子没有 linter 或编译保护,如果使用不当会在运行时发生恐慌。它确实有效,并且可以让您在等待本机实现时对抽象类型进行推理。
快乐编码!