目次
概要
今回のブログポストでは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で開発されています。興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。