goでディレクトリ名とpackage名が一致しないとき,importする側はどうなる?
go結構使ってるのに,パッケージの作り方で今更気になってしまったので調べる
物理pathとpackage名は合わせたほうがいいというのはわかる.わかるが...
異なってしまったとき,どうなるのか,がよくわからない.
基本的 module名をrepositoryに,
repository内部でさらにディレクトリを切って,同名packageを作る,という方針にすべきというのは理解した.
ディレクトリ名とpackage名が異なるのは,mainパッケージのケースだけにすべき.
なぜなら,build後のバイナリを利用するので,goのライブラリとして利用することはないから.
(ここで疑問なのだが,別moduleのmainパッケージってimport可能なのだろうか?)
(ここで疑問なのだが,別moduleのmainパッケージってimport可能なのだろうか?)
試した結果,mainパッケージはimportできない.(それはそう)
たとえばgithub.com/miyataka/gomoduletest
のようなrepository(かつmodule)が存在し,かつそのrepositoryのルートディレクトリではpackage hoge
が定義されていたとする.
そういうケース(moduleのroot directoryで定義されているpackageがrepository名と一致しないケース)の場合,使う側でrenameする必要がある.
具体的にはこのような感じ
package main
import (
h "github.com/miyataka/gomoduletest"
)
func main() {
h.Hoge()
}
類似ケースとして,別にdirectory名とpackage名が一致していないケースもrenameが必要になる.
package main
import (
h "github.com/miyataka/gomoduletest"
"github.com/miyataka/gomoduletest/fuga" // package name == directory name
b "github.com/miyataka/gomoduletest/fumu" // package name != directory name
)
func main() {
h.Hoge()
fuga.Fuga()
b.Bar()
}
つまり,importではURLと一致させる必要があり,package名と一致している場合はその末尾がそのままpackage識別名として利用できるが,一致してないケースでは常にrenameする必要がある.
ちなみにdot importだとrenameする必要はない
package main
import (
h "github.com/miyataka/gomoduletest"
"github.com/miyataka/gomoduletest/fuga" // package name == directory name
. "github.com/miyataka/gomoduletest/fumu" // package name != directory name
)
func main() {
h.Hoge()
fuga.Fuga()
Bar()
}
つまり,
- directory名とpackage名が一致する場合,import時に指定したsuffixがpackage名と一致しているはずなので,renameは必要ない.
- directory名とpackage名が一致しない場合,import時に指定したsuffixがpackage名と不一致なので,renameが必須になる(ただし,dot importはpackage指定する必要がなくなるので,異なる)
そしてmodule名とrepository名が異なり,かつrepository rootに配置してあるpackageがrepository名と一致しないケースは,後者と捉えることができる
この本の1.4.1にコラム?とその監訳注として記載されていた
[2023/09/25 追記]
Go公式が、go moduleをどのように管理すべき(ディレクトリ構成をどうすべき)かの指針を公開した