错误:类型CustomStruct不是表达式。
type CustomStruct struct {
}
func getTypeName(t interface{}) string {
rt := reflect.TypeOf(t).Elem()
return rt.Name()
}
getTypeName(CustomStruct)
Run Code Online (Sandbox Code Playgroud)
如何在没有类型实例的情况下将结构类型传递给函数?
这会起作用
getTypeName((*CustomStruct)(nil))
Run Code Online (Sandbox Code Playgroud)
但我想知道是否还有更简单的版本。
你不能 您只能传递一个值,而CustomStruct不是值,而是一种类型。使用类型标识符是编译时错误。
通常,当要传递“类型”时,您传递一个reflect.Type描述该类型的值。这是您在中“创建”的内容getTypeName(),但是getTypeName()剩下的工作就很少了:
func getTypeName(t reflect.Type) string {
return t.Name()
}
// Calling it:
getTypeName(reflect.TypeOf(CustomStruct{}))
Run Code Online (Sandbox Code Playgroud)
(也请不要忘记,对于诸如的匿名类型,它会返回一个空字符串[]int。)
另一种方法是nil像您一样传递“类型化”的指针值,但是同样,您也可以使用类型化的nil值创建对象reflect.Type,而无需创建相关类型的值,如下所示:
t := reflect.TypeOf((*CustomStruct)(nil)).Elem()
fmt.Println(t.Name()) // Prints CustomStruct
Run Code Online (Sandbox Code Playgroud)
让我们复活这个吧!
Go 的泛型提案获得了批准,并且最终即将到来。当这个问题第一次被问到时,这可能作为一个问题更有意义,但对于现在想要实现泛型模式的任何人来说,我认为我已经有一个不错的 API 了。
目前,您无法与抽象类型交互,但可以与抽象类型上的方法交互,并且 Reflect 允许您检查函数签名。对于方法来说,第 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())
}
Run Code Online (Sandbox Code Playgroud)
一些快速说明:
如果您不知道,真正的泛型将在 Go 1.18 中出现。我上面的示例没有 linter 或编译保护,如果使用不正确,则会在运行时出现恐慌。它确实有效,并且可以让您在等待本机实现时对抽象类型进行推理。
快乐编码!