Я понимаю, что обычно, если я хочу получить доступ к переменной вне области видимости из подпрограммы Go, я обязан создать копию, которая будет концептуально принадлежать подпрограмме Go. Это также верно для каналов, или они освобождены?
Effective Go #channels объясняет это словами "может показаться странным писать req := req
, но это [так в оригинале] допустимо и идиоматично в Go, чтобы сделать это», ссылаясь на этот пример кода:
var sem = make(chan int, MaxOutstanding)
// (other code, filling sem, defining process(..), etc., omitted)
func Serve(queue chan *Request) {
for req := range queue {
<-sem
req := req // Create new instance of req for the goroutine.
go func() {
process(req)
sem <- 1
}()
}
}
Мне удалось почти воспроизвести этот код примера в моем собственном проекте (за исключением того, что я использую chan struct{}
, а не chan int
для своего семафора, и объявляю его локальным для функции Serve
). Глядя на это, я задаюсь вопросом, действительно ли доступ к одному и тому же каналу из нескольких одновременных горутин в порядке или требуется что-то вроде sem := sem
.