golang:在Map Value中使用已定义的接口

时间:2017-09-26 18:55:44

标签: dictionary go types interface

在链接的游乐场示例中,我定义了一个类型:

type DoMap map[int]func(Doer) string

我定义的接口类型中的Doer

我在具体类型MyDoer上实现接口。我希望能够构造一个DoMap,其中该映射中的条目包含以下两个函数:

func(Doer) string // this works
func(*MyDoer) string // this doesn't
func(MyDoer) string // more-or-less the same idea, also doesn't

我不能,虽然很明显它们是不同的类型,但我想知道为什么我不能,因为函数确保我必须提供MyDoer来实现Doer

这还不足以确保我履行与该职能部门的合同吗?

还有另一种方法可以达到这个目的吗?

https://play.golang.org/p/sJ2Rg3neL7

更新

有些评论的形式是“它们不同”“这是规范”但我可以将MyDoer传递给接受Doer的函数 - 如果接口已实现:为什么要放置它进入地图会改变结果吗?

更新2

有一个要求解释“真正的问题”以及为什么我不能只使用类型地图的问题。我会尽力而为:

DoMap不能是类型的地图。我正在编写一个库,允许开发人员根据开发人员编写的接受开发人员定义类型(业务消息)的函数(业务逻辑)的输出,简洁地定义成功或失败的状态机。该库的存在是为了确保一系列转换可以序列化并记录在别处,然后由库的第三方用户进行验证。我最初并没有说出这一切,因为它忽略了这一点 - 没有一个简单的答案。

现在我觉得我因为不切实际的问题而烦恼所有人,因为我没有快速拨打Rob Pike,我可能会删除它,除非有人愿意相信我需要做什么我需要做,并提出建议。

1 个答案:

答案 0 :(得分:1)

您没有概述具体问题(原因)。这使得很难建议替代方案,因为看起来你正试图在go中重新创建另一种语言。

按优先顺序,您可以按预期使用类型系统:

type DoMap map[int]func(Doer) string

type Doer interface {
    Do() int
    AlsoDo() int
}

https://play.golang.org/p/uPzoOZiLQG

或者你可以绕过类型系统:

type DoMap map[int]interface{}

https://play.golang.org/p/lfKPkwhOGa

但我不建议 - 更好地使用语言提供的工具,而不是试图使它们变形。

接口的目的是宣传一个关于函数的契约 - 它们需要它们的参数,而不是更多。但是你也想在参数上调用AlsoDo,所以如果你想这样做,就把它放在合同中。然后一切都会按照你的意愿运作。该函数的合同应该在函数旁边发布,如您的示例所示,它应该在您的控制之下。

[编辑] 最后,如果你不控制传入的类型,也许你应该重新思考你的地图的想法。它可能是一个map [int] Doer,Doer是一个接口(你应该控制它)。这使您可以在库中宣传您需要的内容,并且用户可以在其中放置他们想要的任何类型(以及他们想要的任何其他依赖项)。

// Library 
type DoMap map[int]Doer

type Doer interface {
    Do() int
}

// Client 
type MyDoer struct {
    myint int
}

func (d *MyDoer) Do() int {
    fmt.Println(d.AlsoDo())
    return d.myint + 1
}

func (d *MyDoer) AlsoDo() int {
    return d.myint + 2
}

https://play.golang.org/p/cs01C8bSKo

[EDIT2]最后的编辑,如果建立一个fsm管理链,你可能会发现这个小项目鼓舞人心。它绝对应该没有太多麻烦,只是不像你第一次尝试任何类型的函数映射一样:

https://github.com/ryanfaerman/fsm