break in select will not break the outer for loop

董泽润 · · 1958 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

背景

后台广告系统匹配由串行转为并行,涉及到并发数控制和一些资源回收工作,利用channel去做非常容易实现。细节是魔鬼,还是写的少:)

有问题代码示例


有问题代码

代码实现功能很简单,for 循环中接收 N 个 channel 的数据,业务 channel 传送业务数据,最后一个 ch 用来传递取消信号,如果 ch 接收到数据那么退出 for 循环。按照 C-LIKE 习惯,理想的输出肯定这样的:

start cancel

do something 

do something

do something

receive cancel 0

over

但是真实情况是:

start cancel

do something

do something

do something

receive cancel :0receive cancel :0 无数个 receive cancel :0陷入死循环 

channel 特性

先抛开问题,简单列一个 channel 的特性

1. buffered channel 和 unbuffered channel,缓冲与否的区别

2. 写入关闭的 channel 会导致panic

3. 数据未消费完的 buffered channel 关闭后,是可以读到未消费数据

4. 无数据的 channel 关闭后,可以立刻读到该类型的零值

死循环原因

上面列的 channel 特性只是为了凑数 ~~

Golang 中的 break 有两种写法,一个是 break, 一个是 break [label], 见官方文档,经过测试有如下结论:

1. 不带 label 的break,只能退出最近的 loop,并且对 select, switch 无效

2. 带 label 的 break,对 for, select , switch 均有效

3. break 的 label 只能附着在同一函数的 for, select 或 switch 语句上,对比来讲 goto 的 label就随意一些

退出的正确姿势



break

或是用 C-Like 的goto


goto

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:董泽润

查看原文:break in select will not break the outer for loop

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1958 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传