Instance new Type (Golang)
Asked Answered
S

2

21

Can anyone tell me how to create a new instance of Type from a string? Reflect?

There are examples but they are for the older (pre Go 1 versions) of the language [:(]

Sherard answered 18/4, 2012 at 13:16 Comment(1)
Please clarify a bit your question, it's not clear to me. It also seem incomplete after the final '('.Perpetuity
D
34

So, if I understand your question correctly, you are asking about how you can create an object when you just have the name of the type as string. So, for example, you might have a string "MyStruct" and you want to create an object of this type.

Unfortunately, that's not easily possible because Go is a statically typed language and the linker will eliminate dead code (or inline parts of it). So, there is no guarantee, that your final executable will even contain the code of "MyStruct".

You can however, maintain a global map[string]reflect.Type manually. For example by initializing this map in the init() function of your packages which defines such discover-able types. This will also tell the compiler that you are using the types. Afterwards, you can use this map to look up the reflect.Type of the type you want to create and use reflect.New to get a pointer to a new object of that type (stored as a reflect.Value). You can extract the object into an interface with something like this:

reflect.New(yourtype).Elem().Interface()

Elem() will de-reference the pointer and Interface() will return the reflected value as an interface{}. See The Laws of Reflection for further details.

PS: There might be a better way to structure your program which doesn't even require reflection and which let the compiler catch more errors. Have you considered using a factory method for example? An other easy solution might be to maintain a map[string]func() interface{} of functions which can be invoked to create a new object with that name.

Dotti answered 18/4, 2012 at 14:47 Comment(1)
How would you implement a factory method within Go?Briony
D
6

Factory with predefined constructors can be based on something like:

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())
    }
}
Debarath answered 10/12, 2013 at 1:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.