2016-08-01 9 views
3

関数内で匿名スコープを使用する時期と理由は誰か教えてください。 (私は実際に何が呼ばれているのかは分かりません)。Golang関数に匿名スコープが含まれています

私は維持するために、いくつかのレガシーコードを与えてきたとの機能のいくつかは、この「スコープ」が含まれている私が前に見たことがない

:私が作成した(デモンストレーション用に簡略化)

func DoSomething(someBoolValue bool) string { 
    if someBoolValue { 
     // do some stuff 
     return "yes" 
    } 
    { 
     // weird scope code 
    } 
    return "no" 
} 

Go Playground実際のコード(エラーをスローする)を示すこれは、変数のスコープとシャドウイングと呼ばれる

+1

2つの異なる変数に同じ識別子が必要な場合、つまりブロック内で 'someBoolValue:=" banana "'を再定義することができます。ブロックの後に渡された値になります。 (同じスコープがfor/if/switch/select/funcブロック内で発生し、他の答えが記載されています) – Plato

答えて

2

移動は、字句ブロックを使用してスコープれる:

1-事前宣言済み識別子の範囲は、宇宙ブロックです。
2 - 定数、型、変数、または (関数ではない)トップレベルで宣言された関数(ただしメソッドではありません)を示す識別子の範囲 はパッケージブロックです。
3インポートされた パッケージのパッケージ名のスコープは、インポート 宣言を含むファイルのファイルブロックです。
4メソッド受信者、 ファンクションパラメータ、または結果変数を示す識別子の有効範囲は、関数本体です。
5 - 関数内で宣言された定数または変数識別子の有効範囲 は、ConstSpecまたはVarSpec(ShortVarDeclは短い の変数宣言)の終わりに始まり、最も内側の末尾の ブロックで終了します。
6 - 関数 内で宣言された型識別子のスコープは、TypeSpecの識別子で始まり、内包ブロックの の終わりで終了します。ブロック内で宣言された識別子は、内部ブロックに再宣言された である可能性があります。内側の 宣言の識別子は有効範囲内にありますが、内側の 宣言によって宣言されたエンティティを示します。

パッケージ句は宣言ではありません。パッケージ名は ではありません。その目的は同じパッケージに に属するファイルを特定し、インポートのデフォルトパッケージ名を指定することです 宣言。

作業のサンプルコード:

package main 

import (
    "fmt" 
) 

func main() { 
    i := 10 
    { 
     i := 1 
     fmt.Println(i) // 1 
    } 
    fmt.Println(i) // 10 
} 

出力:

1 
10 

と見る:ゴーでWhere can we use Variable Scoping and Shadowing in Go?

1

{}構文ブロックを形成します。各ブロックは新しいスコープを定義します。これらは、例えばifforで使用するのと同じブロックです。

あなたのコードに関しては、主に読みやすくするために存在すると思います。囲みスコープで定義された変数を再利用または非表示にして、コードの意図をより明確に宣言する変数名を使用することができます。

これ以外にも、一連の関連する文をグループ分けして読みやすくすることもできます。

動作を理解するには、@ Amdの回答を参照してください。

+1

応答に感謝します。私は彼らが私の例で不必要に使用されたかもしれないと思うが、私は今彼らの正しい使い方を理解している。 – danbondd

関連する問題