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

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

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

Go
暮色呼如 2023-08-21 14:37:08
以这两个片段为例使用父作用域中的 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 回答

?
FFIVE

TA贡献1797条经验 获得超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


查看完整回答
反对 回复 2023-08-21
  • 1 回答
  • 0 关注
  • 90 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信