2017-03-14 6 views
1

エラー変数をグローバルに初期化すると、同じパッケージ内の別の関数とは無関係に見えます。
なぜこのコードがパニングされていないのですか?Golangのグローバルエラー変数は、初期化後もnilのままです。

package main 

import (
    "os" 
    "fmt" 
) 

var loadErr error 

func main() { 
    f, loadErr := os.Open("asdasd") 
    if loadErr != nil { 
     checkErr() 
    } 
    if f != nil { 
     fmt.Println(f.Name()) 
    } 
} 

// panic won't be called because loadErr is nil 
func checkErr() { 
    if loadErr != nil { 
     panic(loadErr) 
    } 
} 

これを実行すると、期待どおりに動作しているようですか?

package main 

import (
    "os" 
) 

var loadErr error 

func main() { 
    _, err := os.Open("asdasd") 
    loadErr = err 
    if loadErr != nil { 
     checkErr() 
    } 
} 

// panic will be called as expected 
func checkErr() { 
    if loadErr != nil { 
     panic(loadErr) 
    } 
} 

答えて

5
func main() { 
    _, loadErr := os.Open("asdasd") 

あなたは、新しい変数loadErr地元の作成、グローバルなものが設定されることはありません。グローバル番号を使用する場合は、(:=ではなく)を使用してください。

編集:あまりにも第2の値を保持するために、あなたは第二の可変を先行宣言する必要があります。

var f *os.File 
f, loadErr = os.Open("asdasd") 

:=が非ローカル変数を考慮し、単に作成しません残念ながら、あなたは、ここに:=を使用することはできませんこの場合はローカル変数です。

+0

を私はより明確にする私の質問を編集しました。私は最終的に使用する必要があります:=現実の状況では私もfを保持する必要があるので –

+1

@ J.Goreyあなたの質問は何ですか?あなたは、グローバル変数をシャドウするローカル変数を作成しています。 – zerkms

2

short variable declarationは、左側の変数が外側のscopeで宣言されている場合に新しい変数を作成します。 の左側にすべての変数が新しくない場合は、の再宣言(これは新しい変数を導入せず、元の値に新しい値を代入するだけです)。

グローバル変数に値を代入する場合は、短い変数宣言を使用せず、単純なassignmentを使用してください。もちろん、一つの変数は、あなたがあまりにも前に他の1宣言する必要があり、前に宣言されたタプルの割り当てのために:あなたはそれがよりコンパクトに書くことができます

var f *os.File 
f, loadErr = os.Open("asdasd") 
if loadErr != nil { 
    // Handle error 
} 

を:

var f *os.File 
if f, loadErr = os.Open("asdasd"); loadErr != nil { 
    // Handle error 
} 

別のオプションもあります短い変数の宣言を使用して、しかし、あなたは「手動」グローバルloadErr変数にエラー値を割り当てる必要があります。

f, err := os.Open("asdasd") 
loadErr = err 
if err != nil { 
    // Handle error 
} 

以上のコンパクト:

f, err := os.Open("asdasd") 
if loadErr = err; err != nil { 
    // Handle error 
} 

可能/関連重複質問を参照してください:How to use global var across files in a package?

関連する問題