March 26th, 2015
##前言
前一篇的一些討論後,接下來有一些更容易出錯的部分可以討論.主要focus Goroutine跟 defer
###Goroutine Closure
主要是這一篇部落格帶出的問題:
func main() {
done := make(chan bool)
values := []string{"a", "b", "c"}
for _, v := range values {
go func() {
fmt.Println(v)
done <- true
}()
}
// wait for all goroutines to complete before exiting
for _ = range values {
<-done
}
}
根據以上的部分,印出的結果不會是 “a”, “b”, “c”.而是 “c”, “c”, “c” 原因是 goroutine 變數會參照到go func 跑的時候.
如果修改成以下就可以避免這個問題:
func main() {
done := make(chan bool)
values := []string{"a", "b", "c"}
for _, v := range values {
go func(obj string) {
fmt.Println(obj)
done <- true
}(v)
}
// wait for all goroutines to complete before exiting
for _ = range values {
<-done
}
}
由於他的順序會是 go func(v)
之後才執行,所以其變數內容會先傳過去而不是跑道fmt.Println(v)
才取得. 更多跟goroutinem與closure有關的資訊請看這裡Go: FAQ