web-dev-qa-db-ja.com

var vs:= in Go

Go Webサーバーの例: http://golang.org/doc/effective_go.html#web_server

次のコード行は機能します

var addr = flag.String("addr", ":1718", "http service address")

しかし、それをに変更します

addr := flag.String("addr", ":1718", "http service address")

コンパイルエラーです。どうして?関数の戻り値の型がstringではなく*stringであるという面と関係がありますか?それはどのような違いをもたらしますか?

[〜#〜] update [〜#〜]:=はトップレベルでは許可されていないことを指摘していただきありがとうございます。この不一致が仕様に含まれている理由はありますか?ブロック内で動作が異なる理由は見当たりません。

29
Sudhir Jonathan

更新された質問について:実際には、長い宣言と短い宣言には違いがあり、その短い形式であると変数の再宣言が可能になります。

spec から:

通常の変数宣言とは異なり、短い変数宣言は、変数が同じブロックで同じタイプで以前に宣言されていて、空白以外の変数の少なくとも1つが新しい場合に、変数を再宣言できます。結果として、再宣言は多変数の短い宣言にのみ表示されます。再宣言は新しい変数を導入しません。元の値に新しい値を割り当てるだけです。

field1, offset := nextField(str, 0)
field2, offset := nextField(str, offset)  // redeclares offset
a, a := 1, 2                              // illegal: double declaration of a or no new variable if a was declared elsewhere

だから私は:=演算子は純粋ではありませんdeclareですが、declare and assignに似ています。トップレベルでの再宣言は許可されていないため、短い宣言も許可されていません。

これのもう1つの理由は、構文の単純さです。 Goでは、すべてのトップレベルフォームはtypevar、またはfuncのいずれかで始まります。そこでの短い宣言はすべてのかわいらしさを台無しにします。

12
Mikola

Goでは、トップレベルの変数割り当て必須プレフィックスとしてvarキーワードを付けます。 varキーワードの省略は、ブロック内でのみ許可されます。

package main

var toplevel = "Hello world"         // var keyword is required

func F() {
        withinBlock := "Hello world" // var keyword is not required
}
18
publysher

Goプログラミング言語仕様

短い変数宣言

短い変数宣言は次の構文を使用します。

ShortVarDecl = IdentifierList ":=" ExpressionList .

短い変数宣言は、関数内にのみ表示される場合があります。

あなたの例では、関数本体の外で変数宣言ステートメントを変更します

var addr = flag.String("addr", ":1718", "http service address")

関数本体の外側の短い変数宣言ステートメントへ

addr := flag.String("addr", ":1718", "http service address")

コンパイラエラー「関数本体外の非宣言ステートメント」で失敗します。

5
peterSO