Go语言中关闭channel的两种方式及chan是否按引用传递的疑问
关于Go中Channel传递方式的解答
你的两种示例效果一致,但这不代表channel是按引用传递的——Go语言中所有参数都是按值传递的,channel也不例外。
核心原因
当你把一个channel传给函数或者在goroutine中使用时,传递的是这个channel值的副本,而这个值本身是一个指向底层channel数据结构的指针。也就是说,原channel和传递后的副本指向的是同一个底层对象。因此不管你在哪个goroutine里调用close(),都是对同一个底层channel执行关闭操作,自然效果完全一致。
结合你的示例说明
- 在「示例1」中,
Wakeup函数接收的wakeupChan是main函数中创建的channel的指针副本,它指向的底层channel和main里的是同一个,所以defer close(wakeupChan)关闭的就是原channel。 - 在「示例2」中,匿名goroutine里的
wakeupChanAnother同样是原channel的指针副本,调用close()时也是操作同一个底层channel,所以和示例1的效果没有区别。
澄清误区
很多人会误以为slice、map、chan是引用传递,其实这是误解。Go里没有引用传递,这些类型的“值”本身是指向底层数组/哈希表/channel结构的指针,传递时复制的是这个指针,所以看起来像是引用传递,但本质还是值传递——如果你在函数里把参数重新赋值为另一个channel,原channel不会受到影响,这就能证明它不是引用传递。
内容的提问来源于stack exchange,提问作者user6277806
相关产品推荐
相关产品推荐

