How can I create an object when I am only having its type in string? I am looking for something like:
type someStruct struct {}
resultObject := new \"someStruct
No...
Well, the answer is "yes, but" and it's a big but. There's no central registry of struct names in Go. You're not going to get a nice, clean standard library function called StructFromName(string)
which is probably what you were hoping for.
Instead, you have to write that mapping yourself, something like
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)
}
}
You can't directly do that in Go. The only thing close to that Go supports is reflect.New()
in the reflection library, which accepts a reflect.Type
object and creates a new value of its type.
Now, if you'd like to initialize a type instance by name, you can build a registry of types by name, and have a function that looks up the type by name and creates an instance. It's really ugly though and not very idiomatic to Go, but it can be done.
[EDIT] here's a working example of this. You still need to do type conversion manually:
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))
}
And again, I wouldn't advise you to do this, it's ugly and slow and non idiomatic