目次
概要
今回のブログポストではGolangでModule(モジュール)を使う方法について説明します。このブログポストで紹介するコードは次のリンクで確認できます。
モジュール
Golangのバージョン1.11以前にはモジュールと言うありませんでした。1.11バージョンで初めてモジュールが紹介され、1.13でモジュール機能が完成されました。1.13ではモジュールはOptional機能でしたが、1.16バージョンからGolangの基本仕様になりました。
Golangでモジュールはパッケージ(Package)の集まりで、1つのモジュールは複数のパッケージを含むことができます。このモジュールを使ってGolangではパッケージの依存関係を管理することができ、モジュールはパッケージ管理システムとして活用されてます。
モジュールはパッケージをツーリとして管理して、ルート(root)フォルダにgo.modファイルを生成してモジュールを定義して、依存関係を管理します。
go mod init
Golangでは次のコマンドを使ってモジュールを生成することができます。
go mod init MODULE_NAME
この時モジュールの名前はユニークである必要があります。したがって、GitHubのレポジトリを活用したり何かのURLをモジュール名前として使います。
go mod init github.com/dev-yakuza/study-golang/module/greeting
greetingモジュール
そしたら、例題を作ってみてGolangのモジュールを理解してみましょう。まず、他のモジュールで参照するgreetingモジュールを作ってみます。
mkdir greeting
cd greeting
touch main.go
greetingモジュールを作るためgreetingフォルダを生成してgreetingフォルダ中にmain.goファイルを生成して次のように修正します。
package greeting
import "fmt"
func Hello(name string) string {
message := fmt.Sprintf("Hello, %s", name)
return message
}
greetingモジュールはgreetingと言うパッケージを持っています。
package greeting
greetingのパッケージにはHelloと言う関数があり、その関数は他のパッケージでも使えるようにPublic関数(大文字で始まる)で作成されてます。
func Hello(name string) string {
message := fmt.Sprintf("Hello, %s", name)
return message
}
Hello関数はnameパラメーターを貰ってHello, NAMEで文字列をリターンします。
greetingモジュール生成
このように作成したgreetingパッケージを次のコマンドを使ってモジュールを生成します。
# cd greeting
go mod init github.com/dev-yakuza/study-golang/module/greeting
コマンドを実行すると、当該フォルダにgo.modファイルを生成されることが確認できます。
module github.com/dev-yakuza/study-golang/module/greeting
go 1.17
hello モジュール
次はgreetingモジュールを使うhelloモジュールを生成してみましょう。
# cd ..
mkdir hello
cd hello
touch main.go
greetingフォルダと同じ位置にhelloフォルダを生成します。そして、生成したフォルダにmain.goファイルを生成して次のように修正します。
package main
import (
"fmt"
"github.com/dev-yakuza/study-golang/module/greeting"
)
func main() {
message := greeting.Hello("John")
fmt.Println(message)
}
このように作ったhelloモジュールはmainパッケージとmain関数を持っています。つまり、プログラムをスタート時点を持ってることを意味します。このプログラムは私たちが先ほど作ったgreetingモジュールを使う予定です。greetingモジュールを使うため、上で作ったモジュールの名前を使います。
import (
"fmt"
"github.com/dev-yakuza/study-golang/module/greeting"
)
そしてgreetingモジュールが提供するHello関数を使ってメッセージを出力します。
func main() {
message := greeting.Hello("John")
fmt.Println(message)
}
このようにプログラムを作成したら次のようにgreetingパッケージを探せないエラーが発生します。
could not import github.com/dev-yakuza/study-golang/module/greeting (cannot find package "github.com/dev-yakuza/study-golang/module/greeting" in any of
/usr/local/Cellar/go/1.17/libexec/src/github.com/dev-yakuza/study-golang/module/greeting (from $GOROOT)
/Users/jeonghean/go/src/github.com/dev-yakuza/study-golang/module/greeting (from $GOPATH))compilerBrokenImport
次はhelloモジュールを作成して、greetingモジュールを使えるように修正してみましょう。
helloモジュール生成
下記のコマンドを使ってhelloモジュールを生成します。
go mod init github.com/dev-yakuza/study-golang/module/hello
コマンドを実行すると、helloフォルダの中にgo.modファイルが次のように生成されることが確認できます。
module github.com/dev-yakuza/study-golang/module/hello
go 1.17
go mod tidy
Golangで基本的に提供されるパッケージではなく、外部のパッケージを使う時、当該パッkー時をダウンロードする必要があります。この時、モジュール中で次のコマンドを実行して外部パッケージをダウンロードします。
go mod tidy
しかし、私たちが作ったgreetingパッケージはまだ公開されてないので(GitHubなどにコードを公開してないので)、次のようなエラーが出ます。
go: finding module for package github.com/dev-yakuza/study-golang/module/greeting
github.com/dev-yakuza/study-golang/module/hello imports
github.com/dev-yakuza/study-golang/module/greeting: module github.com/dev-yakuza/study-golang@latest found (v0.0.0-20211026013945-559aef3c74a0), but does not contain package github.com/dev-yakuza/study-golang/module/greeting
この場合は、greetingモジュールをGitHubに上げて、外部に共有することで解決することもできます。他の方法はgo.modを使ってローカルパッケージを参照するように変更することです。
go mod edit -replace
そしたら、go.modを使ってローカルパッケージを参照するように変更してみます。次のコマンドを実行して、ローカルパッケージを参照するように変更します。
go mod edit -replace github.com/dev-yakuza/study-golang/module/greeting=../greeting
そして再び、次のコマンドを実行してパッケージを設定します。
go mod tidy
実行
全ての準備が終わりました。今まで作業した内容を確認するためhelloフォルダで次のコマンドを実行してみます。
# cd hello
go run main.go
このように実行したら、次のような結果が出力されます。
Hello, John
外部モジュールのフォルダー
Golangで次のコマンドを実行すると外部で作成されたモジュールがダウンロードされ、プログラムで使えることができます。
go mod tidy
このようにダウンロードされたモジュールはGOPATH/pkgに保存されます。
go env
上のコマンドを実行すると次のようにGOPATHのパスが分かります。当該フォルダに移動するとpkgフォルダを確認できます。
...
GOOS="darwin"
GOPATH="/Users/dev-yakuza/go"
GOPRIVATE=""
...
完了
これでGolangでモジュールでは何か、どう使うのかについてみてみました。今からはモジュールを使って外部のパッケージを使ってみたり、外部で使えるパッケージを提供してみてください。
私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!
アプリ広報
Dekuが開発したアプリを使ってみてください。Dekuが開発したアプリはFlutterで開発されています。興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。






