パッケージ
概要
パッケージとはプログラムのグループ分けする機能で、 このパッケージのグループを「名前空間」と呼びます。 パッケージの特性として「機能分割」「名前の重複回避」「再利用」などがあります。
機能分割
パッケージを利用することでグループ分けを行うことができます。 Go言語が用意しているパッケージがいくつかありますが、 各パッケージ毎に機能をサポートする機能がしっかりと分かれています。 このようにパッケージは機能ごとで分けることが多いです。
パッケージ名 | 機能 |
---|---|
fmt | 入出力に関する機能< |
time | 日付や時間に関する機能 |
string | 文字列操作に関する機能 |
名前の重複回避
関数や変数、構造体などプログラムを作るために様々なものに名前をつけますが 名前の重複は許可されておらず、エラーになります。func calculate(val01 int, val02 int) { return (val01 + val02) } func calculate(val01 int, val02 int) { return (val01 - val02) }
上のコードでは関数が2つあり、内容は足し算と引き算を行っていますが、 名前が両方ともcalculateです。 Goの関数は名前で識別するので、calculateで2つの違いを識別できません。 この問題を解決する方法としてパッケージ分けがあります。// パッケージadd func Calculate(val01 int, val02 int) int { return (val01 + val02) } // パッケージsub func Calculate(val01 int, val02 int) int { return (val01 - val02) } // パッケージmain import ( "fmt" "add" "sub" ) func main() { fmt.Println(add.Calculate(1, 2)) // 3が出力される fmt.Println(sub.Calculate(1, 2)) // -1が出力される }
上のコードでは足し算を「add」、引き算を「sub」パッケージに移動しました。 これによってCalculateが「addパッケージで書かれているCalculate」と 「subパッケージで書かれているCalculate」となったので、 2つのCalculateの識別が可能となりました。 このように同じ名前の関数、変数などの重複を回避することができます。
再利用
パッケージで作成したプログラムはパッケージのソース毎、 別のプロジェクトに移したり、ワークスペースに移動させたりすることで 簡単に使いまわすことができます。 これはプロジェクトの工数削減に非常に効果的です。
パッケージの使い方
パッケージには基本的なルールが存在し、そのルールに則って「パッケージ宣言」と 「インポート宣言」をすることで使用することできます。
ルール
パッケージ使用のルールは以下のようなものがあります。
1つ以上のパッケージが必要
Go言語では1つ以上のパッケージが必要です。 ソースファイルは必ず1つのパッケージに所属させる必要があるので、 パッケージの宣言をしない場合はエラーになります。 また、プログラムを実行させるためには「main」パッケージが必須です。
複数にソースファイルで使える
パッケージは複数のソースファイルに設定することができます。 例えばimageというパッケージを宣言した場合、複数のソースファイルに imageパッケージを設定することができます。 これによって、1つのファイルが大きくなりすぎることを防げます。
ディレクトリで管理
パッケージはディレクトリ単位で管理を行います。 1つのディレクトリには1つのパッケージしか使用できません。 新しいディレクトリを作成することで、 別のパッケージを作成することは可能です。
ディレクトリ == パッケージ名
絶対ではありませんが、パッケージの名前は基本的に ディレクトリの名前を使用するようにしています。 これは管理をしやすくする効果あるので、mainパッケージ以外は 何か理由がない限りは同じ名前にして下さい。
公開制限
パッケージで作成する関数などの名前の付け方で公開制限の有無が発生します。 「外部に公開していい場合は名前の頭文字を大文字」にして、 「非公開にしたい場合は名前の頭文字を小文字」にしてください。 これによって、外部で使われたくない関数などに制限がつけれるので、 意図とは異なる使用を防ぐことができます。
パッケージ宣言
Goではソースファイルは自分が所属しているパッケージを宣言する必要があります。 パッケージの宣言には「package」を使用します。
書式 | package パッケージ名 |
具体例 | package main |
命名規則
packageで宣言する名前は全て小文字でなおかつ1単語が理想されています。 また、先頭の文字に数字を使うことはできません。 上の「ディレクトリ == パッケージ名」でも書いていますが、 管理のしやすさからディレクトリ名をそのままパッケージ名に使われてることが多いです。
同パッケージの特性
同じパッケージ同士のソースファイルは関数やグローバル変数、構造体などを 共有することができるので、ファイルが異なっても使用可能となります。
インポート宣言
別のパッケージを使うには「import」を使用して宣言する必要があります。 importはパッケージのパス込みで指定しますが、 このパスの種類は「標準パッケージのパス」「相対パス」 「ワークスペースのパス」の3種類です。
基本 | import パッケージディレクトリのパス |
標準の例 | import "fmt" |
相対の例 | import "./add" |
ワークスペースの例 | import "add" |
標準パッケージのパス
標準パッケージとはGo言語が用意してくれているパッケージの事で、 一例ですが、以下のようなものがあります。
パッケージ名 | 機能 |
---|---|
fmt | 入出力機能 |
os | OS関連の機能 |
strings | 文字列操作機能 |
time | 日付や時間関連の機能 |
相対パス
相対パスは現在のパッケージのディレクトリをルートとして、 importするパッケージまでのパスを記述します。 自作のパッケージを使う場合はこの方法を使用します。 自分のフォルダ以下に移動するなら「./」階層を上に 移動するなら「../」を記述します。
ワークスペースのパス
Goでは外部のパッケージを使用する場合、ワークスペースという場所に保存します。 このワークスペースにはGitHubなどで公開されているパッケージをダウンロードして 保存しておくことができます。 ワークスペースのパスでは標準パッケージのパスと同じに見えますが、 実際は「$GOPATH」で設定されているパスが宣言しているパスの前に追加されます。 ワークスペースをルートとしてimportするパッケージのパスを記述します。
複数インポート
複数のパッケージをimportして使いたい場合、1つ1つに対してimportを書かずに
以下のように省略することが可能です。
import (
"パッケージA"
"パッケージB"
"パッケージC"
)