19

谁能告诉我如何从字符串创建一个新的 Type 实例?反映?

有一些示例,但它们适用于语言的较旧(Go 1 之前的版本)[:(]

4

2 回答 2

33

因此,如果我正确理解了您的问题,那么您是在询问当您将类型名称作为字符串时如何创建对象。因此,例如,您可能有一个字符串“MyStruct”,并且您想创建一个这种类型的对象。

不幸的是,这并不容易,因为 Go 是一种静态类型语言,并且链接器将消除死代码(或它的内联部分)。因此,不能保证您的最终可执行文件甚至会包含“MyStruct”的代码。

map[string]reflect.Type但是,您可以手动维护全局。例如,通过在init()定义此类可发现类型的包的函数中初始化此映射。这也将告诉编译器您正在使用这些类型。之后,您可以使用此映射查找要创建的类型的reflect.Type ,并使用reflect.New获取指向该类型的新对象的指针(存储为 reflect.Value)。您可以使用以下方式将对象提取到接口中:

reflect.New(yourtype).Elem().Interface()

Elem()将取消引用指针,并且Interface()将反射值作为interface{}. 有关详细信息,请参阅反射定律

PS:可能有更好的方法来构建您的程序,它甚至不需要反射,并且可以让编译器捕获更多错误。例如,您是否考虑过使用工厂方法?另一个简单的解决方案可能是维护一个map[string]func() interface{}函数,可以调用这些函数来创建一个具有该名称的新对象。

于 2012-04-18T14:47:33.207 回答
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())
    }
}
于 2013-12-10T01:17:20.793 回答