2017-07-10 9 views
0

が行く1.8で評価された、以下ゴー機能(playground)を考えてみましょう:Goでは、値はマルチバリューの割り当てにいつコピーされますか?

func f() (int, bool) { 
    i := 0 
    c := make(chan bool) 
    go func() { 
    time.Sleep(1 * time.Second) 
    i = 1 
    c <- true 
    }() 

    // In practice, `i` will always be 0 here. 
    return i, <-c // returns 1, true 
} 

をコメントで述べたように、機能がciが値をもたらした、常にコピーしているようです。 return文が出てから1秒後に起こるので、これは私が期待したものではありません。

リターンで値の順序が逆になっている場合と、リターンが代入に置き換えられた場合の動作は同じです。

私はこの動作が間違っていると主張しているわけではないことに注意してください。実際には、これはほとんどいつもあなたが起こりたいものです。

このように意図された/指定された動作が信頼できるのかどうかは疑問です。

receive operatorの仕様のセクションでは、このような場合にスレッドをブロックするタイミングを正確に示していません。

答えて

1

order of evaluationに仕様セクションによれば、機能及びこのようなステートメントの操作は左から右に評価され、受信:

例えば、(関数ローカル)割り当て

y[f()], ok = g(h(), i()+x[j()], <-c), k() 

ファンクションコールと通信は、f(),h(),i()j()<-cg()、およびk()の順番で発生します。 しかし、これらのイベントの順番は、評価と索引付けとの順番は、xyです。

しかし、強調された文章に記載されているように、変数評価の順序は指定されていません。

セクションでは、このより明確になり、別の例を示します:

a := 1 
f := func() int { a++; return a } 
x := []int{a, f()} 
// x may be [1, 2] or [2, 2]: evaluation order between a and f() is not specified 

行動が望まれている間ので、それは残念ながら指定されていないとあてにすることはできません。

関連する問題