有人能告诉我如何从字符串创建Type的新实例吗?通过反射?
虽然有例子,但它们是针对较旧版本的语言(Go 1之前的版本)[:(]
有人能告诉我如何从字符串创建Type的新实例吗?通过反射?
虽然有例子,但它们是针对较旧版本的语言(Go 1之前的版本)[:(]
如果我理解你的问题正确,你想知道如何在只有类型名称的字符串时创建对象。例如,您可能有一个字符串"MyStruct",希望创建该类型的对象。
不幸的是,在Go中这是不容易实现的,因为它是一种静态类型语言,链接器将消除死代码(或其中的行内部分)。因此,不能保证最终的可执行文件甚至包含"MyStruct"的代码。
但是,您可以手动维护一个全局的map[string]reflect.Type
。例如,在定义此类可发现类型的包的init()
函数中初始化此映射。这也会告诉编译器您正在使用这些类型。然后,您可以使用此映射查找要创建的类型的reflect.Type并使用reflect.New获取指向该类型新对象的指针(存储为reflect.Value)。您可以使用类似以下方式将对象提取到接口中:
reflect.New(yourtype).Elem().Interface()
Elem()会引用指针,而Interface()则将反射的值作为interface{}
返回。请参阅Reflection法则了解更多细节。
PS: 可能有更好的程序结构方式,不需要使用反射,这样编译器可以捕获更多错误。你考虑过使用工厂方法模式吗?另一种简单的解决方案可能是维护一个map[string]func() interface{}
函数映射表,通过调用相应名称的函数来创建新对象。
预定义构造函数的工厂可以基于类似以下内容的东西:
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())
}
}