【问题标题】:Is it better to range over channel or use select?越过通道范围或使用选择是否更好?
【发布时间】:2019-05-15 05:38:17
【问题描述】:

伙计们,我想知道如果我只有一种情况(我的频道)并在给定频道关闭时发出结束信号,那么是跨频道还是使用选择更好?

举个例子:

1。 https://play.golang.org/p/3ZFdbgHSKyN

go func() {
    for v := range ch {
        // do some stuff
    }
}()

2。 https://play.golang.org/p/iCCkDge8j72

go func() {
    for {
        select {
        case v, ok := <-ch:
            if !ok {
                return
            }

            // do some stuff
        }
    }
}()

哪种解决方案更受欢迎,为什么?请考虑这样一个事实,即这样的 goroutine 可能会产生很多次(许多工作人员)。

【问题讨论】:

  • @CeriseLimón ye 我说这是一个案例的选择
  • Select with one case 就像一个 switch 只有一个 default case:在混淆比赛中过度使用这些东西。
  • @CeriseLimón 随时将您的评论移至答案

标签: go


【解决方案1】:

除非选择的另一个分支,否则使用以下内容:

for v := range ch {
    // do some stuff
}

代码比问题中提出的for/select更简单、更容易理解。

如果出于某种原因需要在循环内进行接收,请使用以下代码:

 for  { 
     // do some stuff
     v, ok := <-ch
     if !ok { 
        break 
     } 
     // do some other stuff
 }

根据经验,应避免使用单分支选择语句。带有单个分支的 select 在功能上与单独的分支相同。

【讨论】:

    【解决方案2】:

    如果您只是在不需要返回值的完成通道上等待,那么您可以完全放弃 for 循环,因为 chan 会阻塞。例如

    // Verbose
    go func() {
        for {
            select {
                case <-blah.Context.Done():
                    // Cleanup/Close
                    return
            }
        }
    }()
    
    // Simplified
    go func() {
        <-blah.Context.Done():
        // Cleanup/Close (No return required either)
    }()
    

    【讨论】:

    • 这正是我的“简化”版本所做的,没有 for 循环?您只看到详细/不正确的版本吗?即使在我的评论中“那么你可以完全放弃 for 循环”
    猜你喜欢
    • 2020-04-24
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2021-03-03
    相关资源
    最近更新 更多