Go言語 – 8.パッケージ

2019-02-01

Go言語 パッケージ

今回は「パッケージ 」について説明します。
Go言語では、名前空間を分けるための仕組みとして、「パッケージ」を使用します。
モジュール性、カプセル化、分離されたコンパイル、再利用をサポートするものです。
プログラムを分割することで機能を分離し、複雑な状態にしないようにしていきましょう。

パッケージの宣言

上記のコードでは、1行目でパッケージ名somepkgを宣言しています。
これにより、変数SomeVarsomeVar2や関数SomeFuncsomeFunc2somepkgパッケージのメンバとなります。
同パッケージ内のメンバは、無制限に参照することができます。

他パッケージメンバの参照

上記のコードでは、somepkgとは別のパッケージotherpkgを宣言しています。
otherpkgからsomepkgのメンバへアクセスしようとしていますが、これはエラーになります。
他のパッケージのメンバにアクセスするには、import文を使用します。
import文によって読み込んだパッケージのメンバへのアクセスは、パッケージ名.メンバ名という形で行います。

パッケージ別名

パッケージのimport時に、パッケージに別名を付けることができます。
例えば上記のコードではパッケージsomepkgにsomeという別名を付けて使用しています。
パッケージ別名は長いパッケージ名を扱う場合や、同名の別パッケージを複数使用する場合に役立ちます。
なお、別名として.を指定したパッケージは、メンバへのアクセス時にパッケージ名の指定を省略することができます。

折角分けた名前空間を混ぜてしまうことになるので原則的に推奨されませんが、
別パッケージに分けざるを得なかったテストコードから製品コードを参照する場合など、
ごく稀に活用できる場面があります。

メンバの可視性

パッケージのメンバのうち、名前の頭文字が英字大文字で始まるものはimport文を使用することで他パッケージからの参照が可能です。
このようなメンバをパブリックメンバと呼びます。

一方、名前の頭文字が小文字のメンバはimport文を使用しても他パッケージから参照することができません。
このようなメンバをプライベートメンバと呼びます。

パッケージに関する禁則事項

循環参照

二つのパッケージがお互いにもう片方をimportをするとコンパイルエラーになります。
例えば、以下の2つのパッケージは循環参照によりエラーとなります。

複数パッケージの同フォルダへの配置

1つのフォルダ直下に、互いに異なるパッケージが宣言された複数のコードを置くことはできません。
つまり、以下のような構造はエラーになります。

逆に、パッケージが同じソースコードであれば同ディレクトリにいくつでも配置が可能です。

例外

実は、同フォルダに複数パッケージを配置できる例外的なケースが一つだけあります。

ファイル名の(拡張子を除いた)末尾が_testで終わるコードはテストコードとして扱われる(詳しくは別章で説明します)のですが、
テストコードについてはテスト対象のパッケージ名_testというパッケージ名を使用することが許されています。

殆どの場合テストコードはテスト対象のパッケージに含めるため使うことは稀ですが、
先述の循環参照を回避するためにこの仕様を利用するケースがあります。