考慮以下Golang代碼(也對Go Playground):Golang爲什麼在門廊裏處理不同的封閉?
package main
import "fmt"
import "time"
func main() {
for _, s := range []string{"foo", "bar"} {
x := s
func() {
fmt.Printf("s: %s\n", s)
fmt.Printf("x: %s\n", x)
}()
}
fmt.Println()
for _, s := range []string{"foo", "bar"} {
x := s
go func() {
fmt.Printf("s: %s\n", s)
fmt.Printf("x: %s\n", x)
}()
}
time.Sleep(time.Second)
}
此代碼產生以下輸出:
s: foo
x: foo
s: bar
x: bar
s: bar
x: foo
s: bar
x: bar
假設這是不是一些奇怪的編譯器缺陷,我很好奇爲什麼a)s的值在goroutine版本中被不同地解釋,然後在常規的func調用中和b)以及爲什麼將它分配給循環內部的局部變量。
我挖@米切爾的'去func(s字符串){...}(s)'成語。解決這個問題的另一種方式是,Go範圍規則意味着* func在兩個*你的例子都訪問's'的當前值是什麼時候運行; goroutine只是在不同的時間運行。 – twotwotwo 2014-09-18 18:42:39
使用賽跑檢測器運行此代碼應該會發現問題。 – 2014-09-19 00:01:21