質問: コードはgistにあります. code1とcode2で`vd`のスコープが異なります.code1では関数スコープにしてあり,この場合`syscall.Syscall`は成功します.code2ではパッケージ変数になっていますが,この場合は`syscall.Syscall`はエラーを返します. 何が問題を引き起こしているのか教えていただきたいです. go1.4 linux/amd64
回答: golang 等、最近のプログラミング言語はレキシカルスコープを採用しています。 code2 の main 内の vd は `:=` で宣言されていますので、main 関数のスコープ内で新しい同名の変数を宣言している事になります。 この場合、main 内の vd に変更が加えられるだけで、外の vd には何も影響しません。 例えるとこんな感じです。 ``` package main import "fmt" var a = 1 func main() { fmt.Println("test1", a) // 外のaが見える為、1 a = 3 // 外のaを3に変えてしまう var a = 2 fmt.Println("test2", a) // 真上のaが見える為、2 foo() } func foo() { fmt.Println("test3", a) // 外のaが見える為、3 } ``` ただしレキシカルスコープを扱うプログラミング言語でも、途中で変数が宣言される場合の動きが異なる場合がありますので各言語の仕様を確認された方が良いと思います。 例えば JavaScript では途中宣言は関数内全ての参照に影響します。 ``` var a = 1; function result(n, v) { document.getElementById(n).innerText = v; } function foo() { result("test3", a); // 外のaが見える為、1 } (function() { // 関数内でaが宣言されているが初期化されていないので // undefined result("test1", a); a = 3; // 変更しても関数内のaが変わるだけ var a = 2; // 関数内のaが見えるので2 result("test2", a); foo(); })() ``` ``` ``` ``` var a = 1; function result(n, v) { document.getElementById(n).innerText = v; } function foo() { result("test3", a); // 外のaが見える為、1 } (function() { // 関数内でaが宣言されているが初期化されていないので // undefined result("test1", a); a = 3; // 変更しても関数内のaが変わるだけ var a = 2; // 関数内のaが見えるので2 result("test2", a); foo(); })() ```