duanliexi1052 2016-06-04 20:26
浏览 36
已采纳

为什么选择大小写将我的for循环切成两半?

In the following code snippet, tasks is a buffered channel of length 30 that is populated with exactly 30 elements. I'm writing a for loop to operate on each task, which is read in from a channel.

for i := 0; i < len(tasks); i++ {
    fmt.Println(i)
    select {
      case task := <-tasks: 
        fmt.Println(task)
        // Do something

    }
}

fmt.Println("Done")

However, this for loop only runs from 0 to 14. When I vary the length of this channel (which depends on the number of task elements I have), the for loop always only runs for half of len(tasks). Why is this the case?

Background: I use a buffered channel for the tasks because I intend to execute each task in a goroutine, and tasks are dealt with if they fail. But I've currently cut code down to a select case in a for loop, and I'm confused about why the select case causes the for loop to only execute for half the time. I confirm that this for loop has finished executing, and that after the last execution, i is equal to 14 (channel length is 30).

  • 写回答

3条回答 默认 最新

  • duananyantan04633 2016-06-04 20:31
    关注

    len(task) decreased if you read from tasks

    Use empty for to iteratively read all from task.

    for {
        select {
        case task := <-tasks:
            fmt.Println(task)
            // Do something
        }
        if len(tasks) == 0 {break}
    }
    

    Or alternatively you can use range:

    for task := range tasks {
    
        fmt.Println(task)
        // Do something
    
        if len(tasks) == 0 {break}
    }
    

    Do not forget to break this cycles if you don't want to lock you goroutine.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 outlook无法配置成功
  • ¥15 Pwm双极模式H桥驱动控制电机
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换