Обтекание вызова функции в закрытие приводит к неожиданному поведению при использовании goroutines.Объединение вызова функции в закрытие при использовании goroutines
Рассмотрим следующий пример:
package main
import (
"log"
"sync"
"time"
)
var workerNum = 5
var wg sync.WaitGroup
func block() {
dur := 300 * time.Millisecond
//time.Sleep()
select {
case <- time.After(dur): {}
}
}
func startWorker(worker int) {
for i:=0; i < 3; i++{
log.Printf("Worker %d woke up! \n", worker)
block()
}
wg.Done()
}
func main() {
for i:=0; i < workerNum; i++ {
//go func() { startWorker(i) }()
go startWorker(i)
}
wg.Add(workerNum)
wg.Wait()
}
испытания его здесь: http://play.golang.org/p/nMlnTkbwVf
Можно видеть, что упаковка startWorker(i)
Into func() { startWorker(i) }()
результаты вызова только 5-й рабочий.
Похоже, что что-то не так в том, как замыкания захватывают переменные из внешнего пространства. Почему это происходит? Затворы используют метод pass-by-reference для передачи внешних переменных вместо передачи по значению?