这段代码:
import "fmt"
import "time"
func main() {
string_slice:=[]string{"a","b","c"}
for _,s:=range string_slice{
go func(){
time.Sleep(1*time.Second)
fmt.Println(s)
}()
}
time.Sleep(3*time.Second)
}
产生输出“c c c”,而这段代码:
import "fmt"
func main() {
string_slice:=[]string{"a","b","c"}
for _,s:=range string_slice{
s="asd"
fmt.Println(s)
}
fmt.Println(string_slice)
}
产生输出“[a b c]”
第一个建议 for range 迭代引用(它不应该),第二个建议它迭代值的副本(它应该)。
为什么第一个不产生输出“a b c”?
最佳答案
当使用 goroutine 时,你必须假设它会并行运行。所以在这种情况下可能会出现 'c c c' 以及 'b b b' 或 'a a a'
运行此代码的 3 次:
for _,s:=range string_slice \\run t0, t1, t2
您将发送运行此代码的 3 次:
go func(){
fmt.Println(s)
}()//send in t0, t1, t2
因此,根据示例,func() 可能会在 t2 开始运行。在这种情况下,结果将为 'c c c',因为 s 等于最新值 (string_slice[2])。
解决方案是通过 func params 复制值:
for _, s := range string_slice{
go func(x string){
time.Sleep(1*time.Second)
fmt.Println(x)
}(s)
}
或者每次迭代创造新的值(value)
//creating new value per iteration
for i := range string_slice{
s := string_slice[i]
go func(){
time.Sleep(1*time.Second)
fmt.Println(s)
}()
}
关于for-loop - 字符串 slice 的范围不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45941794/