概要
ローカルのパッケージをインポートする際にはまったのでメモ。
結論
先に結論から書くと、
GOPATH配下にインポートしたいパッケージを配置して、go.mod
のreplace
でプロジェクトディレクトリのgo.mod
とリンクさせる必要がありました。
やりたいこと
mainパッケージから別パッケージをインポートして使いたい。
例えば、以下のようなディレクトリ構成で、main.go
からfirst_module.go
をインポートして使う。
work/
├── main.go
└── modules
└── first_module.go
数値を渡したら合計値を計算して返す、といった内容で作ります。
package main
import (
"fmt"
)
func main() {
sl := []int{10, 20, 30}
r := modules.Calculate(sl...)
fmt.Println(r)
}
package modules
func Calculate(i ...int) int {
var num int
for _, v := range i {
num += v
}
return num
}
(goのバージョンは以下です。)
go version go1.15.2
解決までの過程
上記の構成のままでは、以下のエラーとなりfirst_module.go
はインポートできません。
import (
"fmt"
"./modules"
)
could not import ./modules (no required module provides package "./modules")
go.mod
を作っていなかった...
ということで作成します。
go mod init work
GOPATH配下にインポートしたいモジュールをコピーして、require
で指定します。
module
には、プロジェクトのモジュール名を記載します。
require github.com/work/modules
module work
go 1.15
go.mod
を作成したので、一度実行してみます。
$ go run main.go
go: errors parsing go.mod:
/work/go.mod:1: usage: require module/path v1.1.1
どうやらモジュールにバージョンを付与しないと行けないようなので、追記します。
require github.com/work/modules
再度実行してみますが、unknown revisionとか言われます。
$ go run main.go
go: github.com/work/modules@v1.1.1: reading github.com/work/modules/go.mod at revision v1.1.1: unknown revision v1.1.1
GOPATH配下にインポートするモジュールを作成するだけではダメで、
以下のようにreplace
で、プロジェクトディレクトリにリンクさせないといけないようです。
require github.com/work/modules v1.1.1
replace github.com/work/modules => ./modules
module work
go 1.15
これでOKと思いきや、以下のエラーに。
インポートするモジュールを置いているディレクトリにもgo.mod
を作成する必要がありました。
$ go run main.go
go: github.com/work/modules@v1.1.1: parsing modules/go.mod: open /work/modules/go.mod: no such file or directory
ということで、go.mod
を作成し再度実行。
$ go run main.go
60
うまく行きました。
最終的なディレクトリ構成は以下のようになりました。
work/
├── go.mod
├── main.go
└── modules
├── first_module.go
└── go.mod
##【備考】 Go modules(vgo)について
基本的に、プロジェクトディレクトリはGOPATH配下に作成しないといけない、と思っていましたが、
go1.11からGo modules(vgo)
が標準装備となり、すべてGOPATH配下に配置しないといけないということはなくなりました。
go.mod
をプロジェクトルートに配置することでvgoモードで動作し、自分の好きなところにプロジェクトを作成できます。
vgo
:
モジュール管理ツール。go.mod
ファイルで依存モジュールやバージョンを管理する。
go.mod
:
node.jsでいうpackage.jsonのようなイメージ。
go env
でGO111MODULE=on
にすることでGo modules(vgo)
が有効になります。
(-w オプションを付けて環境変数を設定)
$ go env -w GO111MODULE=on
$ go env
GO111MODULE="on"
※ なお、go 1.13以降は、GO111MODULE=on
にしなくてもデフォルトで有効な状態になっています。