如何在go map中存储类型以便稍后进行初始化

时间:2015-05-07 10:36:57

标签: go

我试图实现一个工厂函数,它将返回一个符合接口X合同的多个结构之一的实例。

m := make(map[string] ?)
func init () {
    m["a"] = ?
    m["b"] = ?
}

type X interface { 
    y()
}

type A struct {}
func (a * A) y () {}

type B struct {}
func (b * B) y () {}


function factory(name string) X {
    return &m[name]{}
}

上面的代码只是对我想要实现的内容的简化演示 - 寻找指出这是否可能的指针,或者是否有不同的成语来解决这种要求,即我需要这样做。我失踪了。

2 个答案:

答案 0 :(得分:1)

您可以使用map[string]X,使用X接口(可以引用任何符合X契约的对象的值或指针)

  

或者如果有一种不同的习惯用语来解决我失踪的这种要求?

您也可以使用反射(例如" Instance new Type")来实施您的工厂。

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

您可以在" is there a way to create an instance of a struct from a string?"。

中查看工厂示例

工厂方法(每次返回一个新实例)的更快方法是使用开关(如in this example):

// Create a new Widget interface based on WidgetType and set WidgetInfo
func New(wt WidgetType, wi WidgetInfo) Widget_iface {
    switch wt {
    case Widget_A:
        return newWidgetA(wi)
    case Widget_B:
        return newWidgetB(wi)
    }
    return nil
} 

答案 1 :(得分:1)

如果您有一个简单的值类型,那么就像@VonC所说的那样,您可以使用map[string]X并返回示例值的副本。

除了使用反射之外,我只使用创建函数的映射。就像image包所做的那样 image.RegisterFormat

E.g。 (playground):

package main

import "fmt"

type X interface {
        y()
}

type newXFunc func() X

// Here just a map variable and two functions, but
// this could be a type with two methods instead.

var m = map[string]newXFunc{}

func register(name string, fn newXFunc) {
        m[name] = fn
}

func factory(name string) X {
        return m[name]()
}

func init() {
        // If register is exported than these
        // calls can be in other packages that
        // implement A and B.
        register("a", NewA)
        // For simple things that don't have/need
        // their own stand-alone "new" function.
        register("b", func() X { return B{} })
}

type A struct{}

func (a *A) y() {}
func NewA() X   { return &A{} }

type B struct{}

func (b B) y() {}

func main() {
        a1 := factory("a")
        b1 := factory("b")
        fmt.Printf("%T\n", a1)
        fmt.Printf("%T\n", b1)
}