Go言語のスコープについて

Go言語の情報の可視性についてのルールは単純です。名前(トップレベルの型名、関数名、メソッド名、定数名、変数名、構造体のフィールドおよびメソッド名)の先頭一文字が大文字になっていれば、パッケージの利用者側から参照可能となります。すなわち大文字にしなければ、それが定義されているパッケージ内からしか参照できません。このルールはコンパイラによって実施されるため、絶対的なルールとなっています。この外部パッケージから可視状態であることをGo言語の用語で「エクスポートされた(exported)」と言います。

Goプログラミング言語のチュートリアル - golang.jp


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だよ


参考ページ
golang.jp search results: Makefile