如何在Go中引用接口类型?

时间:2013-06-14 02:49:58

标签: types interface go

我有以下两种类型:

type Routing map[string]Handler

type Handler interface {
    Handle()
}

我有一个名为MyHandler的类型,它满足界面,它看起来像这样:

type MyHandler struct {
}

func (this *MyHandler) Handle() {
    // ...
}

我希望能够做到这样的事情:

// routes is created at the beginning of the program and available
// throughout the lifetime of the script

routes := Routing {
    "/route/here": MyHandler,
})

// ...

// and in another method, this line may be executed several times:

new(routes["/route/here"]).Handle()

我在最后一行收到此错误:

  

routes [“/ route / here”]不是类型

当我将最后一行更改为

routes["/route/here"].Handle()
它显然有效。但是,它只使用Handler的一个实例...我希望每次执行最后一行时都有一个新实例。如何在每次执行最后一行时实例化Handler的新实例?

(我假设在使用new时,旧的将在使用后被垃圾收集。请注意,我没有保存我创建的实例;我只关心调用Handle()方法然后将其销毁。)

1 个答案:

答案 0 :(得分:5)

new()将类型作为参数,并返回指向该类型的清零值的指针。类型不是Go中的第一类值。 New是内置的,因此它不会遵循其他代码所遵循的相同规则。新的需要在编译时知道它将处理什么类型。无法构建类型的地图。

我的建议是使用函数来构建每种类型。

type Routing map[string]func() Handler
routes := Routing {
    "/route/here": func() Handler { return new(MyHandler)},
}

routes["/route/here"]().Handle()

我们正在构建一个返回所需类型的函数映射,而不是构建类型映射。


另一种可能性是使用反射虽然我更喜欢上面的功能方法。对于这个用例,我认为这将是一种滥用反射。

type Routing map[string]reflect.Type
routes := Routing {
    "/route/here": reflect.TypeOf(MyHandler{}),
}

reflect.New(routes["/route/here"]).Interface().(Handler).Handle()

警告,如果MyHandler没有实现Handler,这将使程序崩溃。这种方法放弃了编译时类型检查。