有谁能告诉我如何从字符串创建Type的新实例?反映?
有一些例子,但它们适用于语言[:(]
的旧版本(前Go 1版本)答案 0 :(得分:30)
因此,如果我正确理解了您的问题,那么当您将类型名称作为字符串时,您就会询问如何创建对象。因此,例如,您可能有一个字符串“MyStruct”,并且您想要创建此类型的对象。
不幸的是,这不容易实现,因为Go是一种静态类型语言,链接器将消除死代码(或内联部分)。因此,无法保证您的最终可执行文件甚至包含“MyStruct”代码。
但是,您可以手动维护全局map[string]reflect.Type
。例如,通过在包的init()
函数中初始化此映射来定义此类可发现类型。这也将告诉编译器您正在使用这些类型。之后,您可以使用此映射查找要创建的类型的reflect.Type,并使用reflect.New获取指向该类型的新对象的指针(存储为reflect.Value)。您可以使用以下内容将对象提取到接口中:
reflect.New(yourtype).Elem().Interface()
Elem()将取消引用指针,Interface()会将反射值返回为interface{}
。有关详细信息,请参阅The Laws of Reflection。
PS:可能有一种更好的方法来构建程序,它甚至不需要反射,并且让编译器捕获更多错误。您是否考虑过使用factory method?另一个简单的解决方案可能是维护map[string]func() interface{}
个函数,可以调用这些函数来创建具有该名称的新对象。
答案 1 :(得分:6)
具有预定义构造函数的工厂可以基于以下内容:
package main
import (
"fmt"
)
type Creator func() interface{}
type A struct {
a int
}
type B struct {
a bool
}
func NewA() interface{} {
return new(A)
}
func NewB() interface{} {
return new(B)
}
func main() {
m := map[string]Creator{}
m["A"] = NewA
m["B"] = NewB
for k, v := range m {
fmt.Printf("%v -> %v\n", k, v())
}
}