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

以这两个片段为例


使用父作用域的 out chan

func 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 返回给调用者,并且这些值将仅从该通道中使用。


一只萌萌小番薯
浏览 100回答 1
1回答

BIG阳

chan是一个引用类型,就像切片或映射一样。go 中的所有内容都是按值传递的。当您将 chan 作为参数传递时,它会创建引用相同值的引用副本。在这两种情况下,通道都可以从父作用域中使用。但是有几个不同之处。考虑以下代码:ch := make(chan int)var wg sync.WaitGroupwg.Add(1)go func() {&nbsp; &nbsp; ch <- 1&nbsp; &nbsp; ch = nil&nbsp; &nbsp; wg.Done()}()<-ch // we can read from the channelwg.Wait()// ch is nil here because we override the reference with a null pointer对比ch := make(chan int)var wg sync.WaitGroupwg.Add(1)go func(ch chan int) {&nbsp; &nbsp; ch <- 1&nbsp; &nbsp; ch = nil&nbsp; &nbsp; wg.Done()}(ch)<-ch // we still can read from the channelwg.Wait()// ch is not nil here because we override the copied reference not the original one// the original reference remained the same
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go