此代码:
import "fmt"
func main() {
string_slice:=[]string{"a","b","c"}
for _,s:=range string_slice{
s="asd"
fmt.Println(s)
}
fmt.Println(string_slice)
}
产生输出“c c c”,而代码为:
const Nit = (function(){
//closure to store instances
const instances = [];
class Nit {
constructor(nit){
//class have only one property immutable
//writeble false to make it explicity
Object.defineProperty(this, 'nit', {
value: nit,
writable: false
});
//if an instance of this value already exists
//return the same reference
if(!instances[this]){
instances[this] = this;
console.log(instances);
}
else{
return instances[this];
}
}
//valueOf garantee instances are comparable
//and interchangeable (because are immutable)
Nit.prototype.valueOf = function(){
return this.nit;
};
return Nit;
})();
产生输出“[a b c]”
第一个建议对范围迭代而不是引用(它不应该),第二个建议它迭代值的副本(它应该)。
为什么第一个产生输出“a b c”?
答案 0 :(得分:0)
使用goroutine时,你必须假设它将以parallelo运行。所以在这种情况下可能会发生&#c c c'同样也是' b b'或者&a 39'
在此代码中运行3次:
for _,s:=range string_slice \\run t0, t1, t2
您将发送 3次此代码:
go func(){
fmt.Println(s)
}()//send in t0, t1, t2
因此,根据示例,func()可能会在t2中开始运行。在这种情况下,结果将是&#39 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)
}
或者每次迭代创建新值
//creating new value per iteration
for i := range string_slice{
s := string_slice[i]
go func(){
time.Sleep(1*time.Second)
fmt.Println(s)
}()
}