web-dev-qa-db-ja.com

Goで変数を宣言する方法が2つあるのはなぜですか、違いは何で、どちらを使用するのですか?

Goリファレンスによると、変数を宣言する方法は2つあります

Variable_declarationsvar count = 0またはvar count intの形式)
そして
Short_variable_declarationscount := 0の形式)

どちらを使用するかを決定するのは非常に混乱していることがわかりました。

私が知っている(これまでの)違いは次のとおりです。

  • 関数のスコープ内でのみ、count := 0形式を使用できます。
  • count := 0は、多変数の短い宣言redeclaredできます。

しかし、私が知る限り、それらは同じように動作します。そして参考文献ではそれも 言う

イニシャライザ式を使用するが型を指定しない通常の変数宣言の場合、((count:=0way)はshorthandです。

私の混乱は:

  • 一方が他方の省略形である場合、なぜそれらは異なる動作をするのですか?
  • Goの作成者は、どのようにして変数を宣言する方法を2つ作成しますか(なぜ1つの方法にマージされないのですか)。私たちを混乱させるだけですか?
  • 落とし穴に落ちてしまった場合に備えて、他に目を離さないことはありますか?
29
armnotstrong

変数宣言 は、変数が宣言されていることを明確にします。 varキーワードは必須で、短く、何が行われるかを表します(ファイルレベルで、コメントを除くすべてがキーワードで始まる必要があります。例:packageimportconsttypevarfunc)。他のブロックと同様に、変数宣言は次のようにグループ化できます。

var (
    count int
    sum   float64
)

短い変数の宣言 でそれを行うことはできません。また、初期値を指定せずに変数宣言を使用することもできます。その場合、各変数はその型のゼロ値を持ちます。 Short変数宣言はこれを許可しません。初期値を指定する必要があります。

Goの指針となる設計原則の1つは、構文を明確にすることでした。多くのステートメントでは、forifswitchなど、ステートメントの本文でのみ使用できるローカル変数を宣言できるので便利です。構文がより簡潔で短く、Short変数宣言はこれらの場合に正当化され、それらが何をするか明確です。

for idx, value := range array {
    // Do something with index and value
}

if num := runtime.NumCPU(); num > 1 {
    fmt.Println("Multicore CPU, cores:", num)
}

もう1つの違い:再宣言

言語仕様からの引用:

通常の変数の宣言とは異なり、短い変数の宣言では、同じブロックで同じ型を使用して最初に宣言された変数が再宣言され、少なくとも1つの空白以外の変数が新しいものである場合に使用されます。結果として、再宣言は、多変数の短い宣言でのみ使用できます。再宣言によって新しい変数が導入されることはありません。元の値に新しい値を割り当てるだけです。

こちらも重宝です。適切なエラー処理を行いたい場合は、err変数を再利用できます。これは、ほとんどの場合、最後の関数呼び出し中にエラーが発生したかどうかを確認するためだけに必要なためです。

var name = "myfile.txt"

fi, err := os.Stat(name) // fi and err both first declared
if err != nil {
    log.Fatal(err)
}
fmt.Println(name, fi.Size(), "bytes")

data, err := ioutil.ReadFile(name) // data is new but err already exists
                                   // so just a new value is assigned to err
if err != nil {
    log.Fatal(err)
}

// Do something with data
46
icza