2012-07-08 11 views
15

短い変数宣言と長い変数宣言とのクロージャスコープの違いは何ですか?スペックの私の読書から

短い変数の宣言は... ...初期化子式が、なしのタイプと通常の変数 宣言の省略形です

http://golang.org/ref/spec

私は2つが同じであると思ったでしょう:

var f func() 
f = func() { 
    ... 
} 

f := func() { 
    ... 
} 

しかし、そうでないようです。私は外側の関数の内部で自己再帰関数をラップしようとしていたが、これは動作します:

func myOuter() { 
    var f func() 

    f = func() { 
     f() 
    } 

    f() 
} 

をしかし、これは、内部機能でundefined: fを言っていません。

func myOuter() { 
    f := func() { 
     f() 
    } 

    f() 
} 

だから違いは何ですか? ショートフォーム宣言でこれを書く方法はありますか、それともそれを長文で書く必要がありますか?

+0

感謝Kissaki、私は間違いなく同じことを2回貼り付けました。 – Joe

答えて

14

f := func() { /* ... */ }は、var f func() = func() { /* ... */ }と同じです(ただし、パッケージレベルでは後者のみが許可されます)。特定のケースでは、ステートメントが右から左に評価されるため、2つのバリアントのどちらも機能しません。解決策は、あなたが既に提案したように、ステートメントを2つに分割することです。 1つは変数を宣言し、もう1つは再帰関数を代入するためのものです。

+1

ありがとう!注文や宣言は私には起こりませんでした。 – Joe

+0

ああ!今、私はこの洞察のおかげで、私のコードを再び固定する必要があります! –

0

最初の2つのコードサンプルは、1つの条件で意味的に同じです。変数に割り当てられている式がコンパイル時に解決される必要があります。

これは、宣言したばかりの変数(または関数)を参照する式を割り当てるときを除いて、すべての状況で同じです。ここでの問題は、golangが右結合的に解析されるので、式を左に代入する前に型を解決しようとします。 declare-assign演算子の左側にある変数を参照する場合、コンパイラがまだ知識を持っていない変数を参照しているため、undefined: fです。同様の結果をもたらすであろう

もう一つの例:xは、まだ割り当てられていないことがより明白であるので、人々は試みることのために、このものの

x := x + 1 

ははるかに少ない一般的です。

関連する問題