如何在Golang中使用字符串新建一个对象

时间:2014-06-09 08:37:11

标签: go

当我只在字符串中输入类型时,如何创建对象? 我正在寻找类似的东西:

type someStruct struct {}

resultObject := new "someStruct"

使用GORP和GORM等不同的ORM库时,这将非常有用和方便。

可以在Golang中完成吗?

2 个答案:

答案 0 :(得分:6)

你不能直接在Go中这样做。唯一接近Go支持的是反射库中的reflect.New(),它接受​​reflect.Type对象并创建其类型的新值。

现在,如果您希望按名称初始化类型实例,则可以按名称构建类型的注册表,并具有按名称查找类型并创建实例的函数。虽然它真的很难看,但并不是非常惯用,但它可以做到。

[编辑]这是一个有效的例子。您仍需要手动进行类型转换:

package main

import (
    "fmt"
    "reflect"
)

//just a couple of structs
type Foo struct {
    Lol string
}

type Bar struct {
    Wut string
}


//this is the registry of types by name
var registry = map[string]reflect.Type{}

// add a type to the registry
func registerType(t reflect.Type) {
    name := t.Name()
    registry[name] = t
}


// create a new object by name, returning it as interface{}
func newByName(name string) interface{} {

    t, found := registry[name]
    if !found {
        panic("name not found!")
    }

    return reflect.New(t).Elem().Interface()
}

func main() {

    //register foo and bar
    registerType(reflect.TypeOf(Foo{}))
    registerType(reflect.TypeOf(Bar{}))

    //create new instances
    foo := newByName("Foo").(Foo)
    bar := newByName("Bar").(Bar)

    fmt.Println(reflect.TypeOf(foo), reflect.TypeOf(bar))
}

再一次,我不建议你这样做,它是丑陋的,缓慢的,非惯用的

答案 1 :(得分:6)

没有...

嗯,答案是"是的,但"这是一个很大的但是。在Go中没有结构名称的中央注册表。你不会得到一个名为StructFromName(string)的漂亮,干净的标准库函数,这可能是你所希望的。

相反,您必须自己编写映射,例如

func StringToStruct(name string) (interface{}, error) {
    switch name {
    case "SomeStruct":
        return SomeStruct{}, nil
    case "SomeOtherStruct":
        return SomeOtherStruct{}, nil
    case "subpackage.Struct":
        return subpackage.Struct{}, nil
    default:
        return nil, fmt.Errorf("%s is not a known struct name", name)
    }
}