Goで自分が書いたコードのパッケージ名については、以下のようにすべてプレフィックスをつけることにしました。
場所 | プレフィックス |
---|---|
アプリケーション | my |
ライブラリ | ハンドル名、会社名などから取った任意の2文字 |
前知識
- Goのパッケージは階層構造を持たない
- 当然、パッケージ名の重複は許容されている
- package textのように宣言した時、参照する際のデフォルト名がtextというだけである
- 参照側で同名のデフォルトパッケージが複数ある場合は、別の名前をつけることで衝突を回避する
衝突回避の例
以下のようなディレクトリ階層の同名パッケージがあるとする。
階層構造 | パッケージ名 |
---|---|
dir1/twitter/foo.go | |
dir2/twitter/bar.go |
foo.go、bar.goで宣言されている変数や関数を参照したい時は、以下のようにimportの際に別のパッケージ名を割り当てる。
import (
"dir1/twitter",
twitter2 "dir1/twitter"
)
この場合、dir1/twitter/foo.goの変数や関数はtwitter.Hoge()のように参照可能。dir2/twitter/bar.goは、twitter2.Puge()のように参照可能。
結論。めんどくさい。こんなことはいちいちやっとれん。
プレフィックス最強説
私はこのパッケージ、いわゆるネームスペース的なものに依存するのがあまり好きではない。なぜかというとコードだけ見ても、それがどのネームスペースに属しているのかわかりづらいからだ。Goはまだ良い。必ず頭にパッケージ名が付くからだ。Javaでは異なるパッケージの同名クラスを参照する際に、com.java.io.Hogeみたく書くが、これも長ったらしくて好きではない。
いずれにせよ、名前衝突は起きる。Goの標準パッケージであるstring、htmlのような汎用的なパッケージ名は、自分も使いたいケースがあるだろう。だから、言語仕様にパッケージやネームスペースがあれどプレフィックスをつけた方が良いと私は考える。それはコードを見た時に自分が書いたものと判別するためにも役に立つ。
というわけで、パッケージ名は自分しかつけないであろう、他のライブラリと重複しないものにすることにした。そして最初に述べたように私はこのようにしている。
オレオレライブラリは、自分のハンドル名から2文字取ったものなどを使う。
- e4string
- e4html
- e4http
アプリケーションレイヤーはmyをつける。
- myapp
- mymodel
- mycontroller
このように何らかのプレフィックスをつけると、ほとんど他と重複しない。プロジェクトツリーに同じプレフィックスのパッケージが並んでいるのは、やや不自然に思うが、私はもう慣れた(笑)ダサいと言われようともわかりやすいさを取ることにした。
また、Goはディレクトリ分けしてもパッケージが階層分けされるわけではないので、基本的にディレクトリは1階層までにしている。2階層目までいくとディレクトリ名=パッケージ名が衝突していてもわかりにくいからだ。1階層に並んでいれば重複することはない。
ちなみにGoはJavaと違いディレクトリ名とパッケージ名が一致している必要はない。が、通常は合わせる。