go - 结构类型作为映射键

标签 go types interface go-map

<分区>

我们有以下功能:

func (h *Handler) Handle(message interface{}) error {
    //here there is a switch for different messages
    switch m := message.(type) {
    }
}

此签名已提供且无法更改。处理程序处理大约 20 种不同的消息类型。

现在,其中一些消息(大约 4 条)需要特殊的后期处理。在不同的包中。

因此,我想这样做:

 func (h *Handler) Handle(message interface{}) error {
        //here there is a switch for different messages

        switch m := message.(type) {
        }
        //only post-process if original message processing succeeds
        postProcessorPkg.Process(message)
    }

现在,在 Process 函数中,我想快速查找消息类型是否确实是我们需要后处理的类型。我不想在这里再次进行 switch 操作。有许多处理程序,在不同的包中,具有不同数量的消息类型,并且它应该是通用的。

所以我想在后处理器中注册消息类型,然后进行查找:

func (p *Postprocessor) Register(msgtype interface{}) {
     registeredTypes[msgtype] = msgtype
}

然后

func (p *Postprocessor) Process(msgtype interface{}) error {
     if ok := registeredTypes[msgtype]; !ok {
        return errors.New("Unsupported message type")
     }
     prop := GetProp(registeredTypes[msgtype])
     doSmthWithProp(prop)
}

这一切现在都行不通了,因为据我所知,我只能“注册”消息的实例,而不是消息类型本身。因此,映射只会匹配消息的特定实例,而不是它的类型,而这正是我所需要的。

所以我想这需要重新设计。我可以完全放弃注册和 map 查找,但是

  • 我无法将 Handle 函数更改为特定类型(签名将需要保留 message interface{}
  • 我想避免必须使用 reflect,因为我很难与一些同事一起捍卫这样的解决方案。

最佳答案

由于无法将类型设置为映射键,我最终决定实现以下解决方案,该解决方案基于@Chrono Kitsune 的解决方案:

type Postprocess interface {
    NeedsPostprocess() bool
}

type MsgWithPostProcess struct {}

func (p *MsgWithPostProcess) NeedsPostprocess() bool {
  return true
}

type Msg1 struct {
   MsgWithPostProcess
   //other stuff
}

type Msg2 struct {
    MsgWithPostProcess
    //other stuff
}

type Msg3 struct {
    //no postprocessing needed
}

func (p *Postprocessor) Process(msgtype interface{}) error {
     if _, ok := msgtype.(Postprocess); ok {
        //do postprocessing
     }         
}

在我做的简单测试中,只有 Msg1Msg2 会被后处理,而不是 Msg3,这正是我想要的。

关于go - 结构类型作为映射键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51800637/

相关文章:

c++ - 处理 map 键中指向值的常量

delphi - 抽象与接口(interface) - 在 Delphi 中分离定义和实现

c# - 如何在界面中配置代码契约

session - 如何检测 session 是否即将过期?

json - Go 中的面向对象 - 结构/组合/封装

nginx - Go:在模板中的 if 语句中使用环境变量

c++ - OpenCV的Mat结构中存储的元素类型

scala - 在 Scala 中解包元组类型

java - 基于访问器方法强制执行严格继承

postgresql - 去 echo : POST Method gives Error "Method not allowed"