[Go语言] 操作channel时遇到panic怎么办?

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

很多同学在使用channel时都遇到过这种情况:Panic问题,相信大家对于这种设计也吐槽了不少吧?这篇文章我们就来扒一扒这样设计的初衷。

潜在的Panic主要有两种: 重复close一个channel,向已经closed的channel继续发送消息。

最懒的解决办法就是通过recover来简单粗暴的恢复,可是这就违背了设计者的初衷。对于channel c来说,内置的close函数表明了不会再有任何值发送到c,重复关闭或者向已经关闭的c发送任何消息都会导致runtime panic,关闭nil channel也会导致panic。

这里有个问题,如果c关闭了,继续从c读取消息会怎么样?不用担心,至少不会有panic发生。首先是从c中读取之前发送但是还没有被接收的消息,当这类消息接收完了,之后接受到的消息都是对应channel类型的零值,要注意的是,从一个关闭的channel中接收消息是完全不会阻塞的!!当然,我们可以通过接收操作的第二个参数来判断channel是否已经关闭,如果关闭,就不要继续接收消息了。

回到上面的recover话题,为什么不提议这么做呢,因为一旦这么做,就意味着你对自己的程序设计时存在什么潜在的bug根本就不清楚,只想着通过异常处理这种最粗暴的方式来解决。向一个还在打开的channel发送消息,就是设计上可能存在的bug!

其实从底层来说,close也是channel上的一次消息发送操作,只不过发送的是一个特殊的关闭消息,该消息就是承诺给系统,该channel绝对不会再收到任何消息。如果继续发送消息,就会违背这种承诺。同时,由于close也是消息发送,因此重复close也会导致panic。

大家应该都知道这个idiom:只应该由发送方来关闭channel。那同学们肯定也有疑问,那如果同一个channel有多个发送方呢?这个就是我们程序设计的问题了,如果多个发送方都要求去关闭channel,但是彼此之间根本就不沟通,那就是有问题的:因为这种情况下,如果某个发送方要关闭channel,却不通知其它发送方,那就存在很大的潜在bug了,至少关闭一个公有频道,需要得到大家的认可才行!

这里附上Rob Pike大神的一段原文翻译:

关闭一个channel就是释放一个资源。多次关闭一个channel就像多次关闭文件描述符、多次释放内存块一样,都是没有任何意义的。这些操作都意味着代码是有问题的,这也是为什么我们设计时就强制产生了panic。


看看,大神果然是大神,一句话就阐述清了问题:都是设计和代码问题!因此让自己的设计和代码清晰明朗起来是非常重要的,能不用recover解决问题就不用。

总之,Go的设计原则就是简洁、清晰、不冗余,用一句流行语来说:我的代码,我做主








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

本文来自:CSDN博客

感谢作者:abv123456789

查看原文:[Go语言] 操作channel时遇到panic怎么办?

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

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