LoginSignup
3
2

More than 5 years have passed since last update.

Goでパッケージ名の衝突を避けるためにプレフィックスをつけることにした

Last updated at Posted at 2017-07-02

Goで自分が書いたコードのパッケージ名については、以下のようにすべてプレフィックスをつけることにしました。

場所 プレフィックス
アプリケーション my
ライブラリ ハンドル名、会社名などから取った任意の2文字

前知識

  • Goのパッケージは階層構造を持たない
  • 当然、パッケージ名の重複は許容されている
  • package textのように宣言した時、参照する際のデフォルト名がtextというだけである
  • 参照側で同名のデフォルトパッケージが複数ある場合は、別の名前をつけることで衝突を回避する

衝突回避の例

以下のようなディレクトリ階層の同名パッケージがあるとする。

階層構造 パッケージ名
dir1/twitter/foo.go twitter
dir2/twitter/bar.go twitter

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と違いディレクトリ名とパッケージ名が一致している必要はない。が、通常は合わせる。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2