【问题标题】:How can I refer to an interface type in Go?如何在 Go 中引用接口类型?
【发布时间】:2013-06-10 14:58:20
【问题描述】:

我有这两种类型:

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() 方法然后将其销毁.)

【问题讨论】:

  • 也许Routing 应该是type Routing map[string](func() Handler) 然后你可以把NewMyHandler 函数放到map 中,每次调用它都会返回一个新函数?
  • 好主意。你应该把这个作为答案!
  • 我几乎不知道我在 Go 中在说什么,所以我害怕 :P 幸运的是其他人完成了所有艰苦的工作来填写细节。

标签: types interface go


【解决方案1】:

new() 将类型作为参数并返回指向该类型的归零值的指针。类型不是 Go 中的一等值。 New 是内置的,因此它不会按照其他代码的相同规则运行。 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,这会使你的程序崩溃。该方法放弃了编译时类型检查。

【讨论】:

  • 奇怪地让人联想到 Javascript 式的做法!我也更喜欢第一种方法。巧妙地使用反射,虽然它让我有点畏缩。
  • "没有办法构建类型映射。"有 -- 使用来自reflect 模块的Type 来存储类型,以及来自reflect 模块的其他函数来使用它。
  • @newacct,这与我在第二个示例中所做的差不多。但是,这与语言中的类型不同。
猜你喜欢
  • 1970-01-01
  • 2017-07-30
  • 2019-05-10
  • 1970-01-01
  • 2021-02-10
  • 2011-02-28
  • 2013-01-04
  • 2023-03-28
  • 2010-09-30
相关资源
最近更新 更多