当我只在字符串中输入类型时,如何创建对象? 我正在寻找类似的东西:
type someStruct struct {}
resultObject := new "someStruct"
使用GORP和GORM等不同的ORM库时,这将非常有用和方便。
可以在Golang中完成吗?
答案 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)
}
}