Go言語のスコープについて
Go言語の情報の可視性についてのルールは単純です。名前(トップレベルの型名、関数名、メソッド名、定数名、変数名、構造体のフィールドおよびメソッド名)の先頭一文字が大文字になっていれば、パッケージの利用者側から参照可能となります。すなわち大文字にしなければ、それが定義されているパッケージ内からしか参照できません。このルールはコンパイラによって実施されるため、絶対的なルールとなっています。この外部パッケージから可視状態であることをGo言語の用語で「エクスポートされた(exported)」と言います。
Go言語でのスコープは3つかな?
- 関数、if 文などの()、{}の中
- Package内
- Packageの外部
同一パッケージ内であれば、異なるファイルでも非公開関数や変数を参照できるみたい。
ある1つのファイルで定義した非公開変数を、同一パッケージ内の他のファイルから参照できるかを確認してみた。
同じ"local"パッケージでlocal1.goとlocal2.goっていう2つのファイルを作成。
local1.go
package local var localStr string = "Localだよ" // <- Package local 内でのみ参照可能 var GlobalStr string = "Globalだよ" // <- Package 外に公開
local2.go
package local import "fmt" func PrintStr() { fmt.Println("local:", localStr) // <- 同一Package内なので参照可能 fmt.Println("local:", GlobalStr) // <- 公開変数なので参照可能 }
上の2ファイルから"local"パッケージを作成するには、こんな感じでMakefieを書けばOK。
#package作成用Makefile nclude $(GOROOT)/src/Make.inc TARG=local GOFILES=\ local1.go\ local2.go\ include $(GOROOT)/src/Make.pkg
makeすると_objディレクトリ以下にlocal.aができるので、それをimportする。
package main import ( "fmt" "./local" ) func main() { local.PrintStr(); // fmt.Println("main:", local.localStr) // <- 参照不可能。コンパイルエラーになる。 fmt.Println("main:", local.GlobalStr) }
実行ファイル用のMakefileは最後のincludeを"Make.cmd"に変える。
include $(GOROOT)/src/Make.inc TARG=scopetest GOFILES=\ localmain.go\ include $(GOROOT)/src/Make.cmd
実行結果
$ ./scopetest local: Localだよ local: Globalだよ main: Globalだよ