为了账号安全,请及时绑定邮箱和手机立即绑定

将通道作为形式参数传递给闭包与使用父范围中定义的通道之间的区别?

将通道作为形式参数传递给闭包与使用父范围中定义的通道之间的区别?

Go
一只萌萌小番薯 2022-05-23 16:09:50
以这两个片段为例使用父作用域的 out chanfunc Worker() {    out := make(chan int)    func() {        // write something to the channel    }()    return out}将 out chan 作为正式参数传递给闭包func Worker() {    out := make(chan int)    func(out chan int) {        // write something to the channel    }(out)    return out}我知道将参数传递给闭包会创建一个副本,并且使用父作用域中的某些东西会使用引用,所以我想知道在通过副本传递的情况下它在内部是如何工作的。是否有两个通道,一个在父范围内,另一个副本传递给闭包,当闭包中的副本写入该值的副本时,该值的副本也在父范围的通道中创建?因为我们将父作用域中的 out chan 返回给调用者,并且这些值将仅从该通道中使用。
查看完整描述

1 回答

?
BIG阳

TA贡献1859条经验 获得超6个赞

chan是一个引用类型,就像切片或映射一样。go 中的所有内容都是按值传递的。当您将 chan 作为参数传递时,它会创建引用相同值的引用副本。在这两种情况下,通道都可以从父作用域中使用。但是有几个不同之处。考虑以下代码:


ch := make(chan int)


var wg sync.WaitGroup

wg.Add(1)

go func() {

    ch <- 1

    ch = nil

    wg.Done()

}()


<-ch // we can read from the channel

wg.Wait()

// ch is nil here because we override the reference with a null pointer

对比


ch := make(chan int)


var wg sync.WaitGroup

wg.Add(1)

go func(ch chan int) {

    ch <- 1

    ch = nil

    wg.Done()

}(ch)


<-ch // we still can read from the channel

wg.Wait()

// ch is not nil here because we override the copied reference not the original one

// the original reference remained the same


查看完整回答
反对 回复 2022-05-23
  • 1 回答
  • 0 关注
  • 99 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号