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

Ant*_*ang 1 go

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

type someStruct struct {}

resultObject := new "someStruct"
Run Code Online (Sandbox Code Playgroud)

当使用不同的ORM库(如GORP和GORM)时,这将非常有用和方便.

可以在Golang中做到吗?

Not*_*fer 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))
}
Run Code Online (Sandbox Code Playgroud)

而且,我不会建议你这样做,它是丑陋的,缓慢的,非惯用的


Lin*_*ope 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)
    }
}
Run Code Online (Sandbox Code Playgroud)