为了账号安全,请及时绑定邮箱和手机立即绑定

处理不同类型的消息 - 一个还是多个频道?

处理不同类型的消息 - 一个还是多个频道?

Go
繁星coding 2021-09-27 10:48:46
考虑这个简单的代码:type Message struct { /* ... */ }type MyProcess struct {    in chan Message}func (foo *MyProcess) Start() {    for msg := range foo.in {        // handle `msg`    }    // someone closed `in` - bye}我想更改 MyProcess 以支持 2 种不同类型的消息。我有两个想法:a) 类型开关type Message struct { /* ... */ }type OtherMessage struct { /* ... */ }type MyProcess struct {    in chan interface{} // Changed signature to something more generic}func (foo *MyProcess) Start() {    for msg := range foo.in {        switch msg := msg.(type) {        case Message:            // handle `msg`        case OtherMessage:            // handle `msg`        default:            // programming error, type system didn't save us this time.            // panic?        }    }    // someone closed `in` - bye}b) 两个通道type Message struct { /* ... */ }type OtherMessage struct { /* ... */ }type MyProcess struct {    in      chan Message    otherIn chan OtherMessage}func (foo *MyProcess) Start() {    for {        select {        case msg, ok := <-foo.in:            if !ok {                // Someone closed `in`                break            }            // handle `msg`        case msg, ok := <-foo.otherIn:            if !ok {                // Someone closed `otherIn`                break            }            // handle `msg`        }    }    // someone closed `in` or `otherIn` - bye}两种实现之间的功能区别是什么?一件事是排序差异 - 只有第一个可以保证消息(Message和OtherMessage)将按正确的顺序处理。哪个更地道?方法 'a' 更短,但不强制消息类型的正确性(可以在通道中放入任何东西)。方法 'b' 解决了这个问题,但有更多的样板文件和更多的人为错误空间:需要检查两个通道的封闭性(容易忘记)并且有人需要实际关闭它们(甚至更容易忘记)。长话短说,我宁愿使用“a”,但它不利用类型系统,因此感觉很丑陋。也许有更好的选择?
查看完整描述

2 回答

?
慕姐8265434

TA贡献1813条经验 获得超2个赞

我也会选择“a”:只有一个频道。如果您创建基本消息类型 (an interface) 并且两种可能的消息类型都实现它(或者如果它们也是接口,则可以嵌入它),您可以强制类型正确性。

单通道解决方案的另一个优点是它是可扩展的。如果现在您想处理第 3 种类型的消息,添加和处理它非常容易。在其他情况下:您将需要第三个通道,如果消息类型的数量很快增加,它将变得难以管理并使您的代码变得丑陋。同样在多通道的情况下,select随机选择一个准备好的通道。如果消息在某些通道中频繁传入,即使通道中只有一条消息并且没有更多消息传入,其他通道也可能会饿死。


查看完整回答
反对 回复 2021-09-27
  • 2 回答
  • 0 关注
  • 163 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信