实例新类型(Golang)

时间:2012-04-18 13:16:46

标签: go types instance go-reflect

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

有一些例子,但它们适用于语言[:(]

的旧版本(前Go 1版本)

2 个答案:

答案 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())
    }
}