You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言通道遍历错误引发死锁与异常输出0的原因咨询

Go语言通道遍历错误引发死锁与异常输出0的原因咨询

咱们来一步步拆解你遇到的这两个问题,都是非常典型的Go通道用法误区哦~

一、为什么会输出“received 0”?

你写的for val := range <-bChan这行代码,本质上是先执行<-bChan从通道读取一个值,但这个值是int类型,而Go的range关键字只能作用于数组、切片、map、通道或字符串,根本不能直接作用于单个整数。

那为啥会输出0呢?其实这行代码在语法上就是错的,正常编译器会直接报错,但你的代码意外运行后出现的这个结果,属于非法用法导致的未定义行为。大概率是某次通道读取操作返回了int类型的零值0(比如通道关闭后读取会返回对应类型的零值),然后错误的range逻辑把这个零值当成了可遍历对象,最终就输出了“received 0”。

二、为什么会发生死锁?

咱们梳理下原代码的执行流程,你就懂了:

  • main函数先创建了容量为2的缓冲通道,写入1和2之后,通道已经被填满了。
  • 启动receiver协程后,main尝试往通道里写3,但通道已满,main会直接阻塞在bChan <-3这行,必须等通道腾出空间才能继续。
  • 但你的receiver协程里的错误代码根本没有在“持续读取通道”:for val := range <-bChan要么因为语法问题直接终止循环,要么只执行了一次非法操作就退出了,完全没起到清空通道的作用。
  • 这下就僵住了:main一直卡着等通道有空位,receiver协程要么已经退出要么卡着不动,所有协程都陷入了互相等待的状态,Go运行时就会触发死锁错误。

而当你改成for val := range bChan后,这个循环会持续从通道里读取值,直到通道被关闭——它会依次把1、2、3、4都读出来,然后执行wg.Done(),main也能顺利写完数据、关闭通道,自然就不会死锁啦。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 09:14:33