Разница между передачей канала закрытию в качестве формального аргумента и использованием канала, определенного в родительской области? - PullRequest
0 голосов
/ 20 марта 2020

Возьмем эти два фрагмента, например:

  • Использование 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
}

Я знаю, что передача аргументов в замыкание создает копию этого, а использование чего-либо из родительской области использует ссылку, поэтому я хочу знать, как это работает внутри в случае проход за копией. Есть ли два канала, один в родительской области, а другая копия передается в замыкание, и когда копия в замыкании записывается в копию этого значения, также создается в канале в родительской области? потому что мы возвращаем исходящий канал в родительской области действия вызывающей стороне, и значения будут использоваться только из этого канала.

1 Ответ

1 голос
/ 20 марта 2020

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...