こんにちは。よっしーです(^^)
今日は、Golangで外部パッケージを作成する方法についてご紹介します。
前提条件
下記の記事が実行できる環境にあることを前提にしていますので、参考にお願いします。
背景
本記事では、別のモジュールから呼び出すことができる関数を含む小さなモジュールを作成します。
Go言語におけるモジュールは、コードのパッケージングと依存関係管理を支援する仕組みです。モジュールを使用することで、複数のパッケージをまとめて管理し、外部の依存関係を明示的に指定することができます。
Goのモジュールは以下の手順に従って作成および使用されます:
- モジュールの初期化: モジュールを初期化するには、新しいディレクトリを作成し、そのディレクトリ内で
go mod init
コマンドを実行します。このコマンドは、現在のディレクトリをルートとする新しいモジュールを初期化します。例えば、go mod init example.com/my-module
というコマンドを実行すると、example.com/my-module
という名前のモジュールが作成されます。 - パッケージの作成: モジュール内でパッケージを作成するには、通常通りにGoのコードを書いてディレクトリに配置します。パッケージ名はディレクトリ名と一致している必要があります。
- 依存関係の管理: モジュールは他のモジュールに依存することができます。依存関係を明示的に指定するためには、
go.mod
というファイルを使用します。このファイルはモジュールのルートディレクトリにあり、モジュールの名前や依存関係が記述されています。依存関係はrequire
ディレクティブを使用して指定します。例えば、require example.com/dependency v1.2.3
という行を追加することで、example.com/dependency
という名前のモジュールのバージョン1.2.3を依存関係として指定できます。 - モジュールの取得: モジュールの依存関係が指定されている場合、
go get
コマンドを使用してそれらの依存関係を取得します。例えば、go get example.com/dependency
というコマンドを実行すると、example.com/dependency
モジュールがダウンロードされ、go.mod
ファイルに依存関係が追加されます。 - ビルドおよび実行: モジュールが正しく初期化され、依存関係が解決されたら、通常のビルドおよび実行コマンド(
go build
やgo run
)を使用してコードをビルドし実行をします。モジュール内のパッケージは、通常のGoのコードと同様にビルドおよび実行できます。
モジュールの管理には、go.mod
ファイルが重要な役割を果たします。このファイルには、モジュールの名前、依存関係、およびバージョン情報が含まれています。また、go.sum
ファイルも生成され、依存関係の正確なバージョンを追跡するために使用されます。
モジュールを使用する主な利点は次のとおりです:
- バージョン管理: モジュールを使用することで、外部依存関係のバージョンを明示的に指定することができます。これにより、予期せぬ変更や互換性のない更新がプロジェクトに影響を与えることを防ぐことができます。
- 依存関係の解決: モジュールを使用することで、依存関係の解決が自動化されます。
go get
コマンドを使用すると、指定した依存関係とその依存関係に対して再帰的に必要なパッケージがダウンロードされます。 - リポジトリの独立性: モジュールを使用することで、パッケージの管理がリポジトリ単位で行われます。これにより、他の開発者がプロジェクトを簡単にビルドおよび実行できるようになります。
モジュールに関する詳細な情報や操作方法については、公式のGoモジュールのドキュメントを参照してください。
作成方法
作業ディレクトリを作成して、移動する。
05_learn-golang-create-module
cd 05_learn-golang-create-module
asdfコマンドで使用するGolangのバージョンを指定します。
すでにGolangが実行できる状態にある方は、このコマンドをスキップしても問題ありません。
asdf local golang 1.20.5
Goモジュールのソースコード用に、greetingsディレクトリを作成します。
mkdir greetings
cd greetings
go mod initコマンドでモジュールを起動します。
go mod initコマンドを実行し、モジュールのパスを指定します。ここではexample.com/greetingsを使用します。モジュールを公開する場合、これはGoツールでモジュールをダウンロードできるパスでなければなりません。これは、あなたのコードのリポジトリになります。
go mod init example.com/greetings
go mod initコマンドは、あなたのコードの依存関係を追跡するためにgo.modファイルを作成します。今のところ、このファイルにはモジュールの名前と、あなたのコードがサポートしているGoのバージョンだけが含まれています。しかし、依存関係を追加していくと、go.modファイルはあなたのコードが依存しているバージョンをリストアップします。これにより、ビルドの再現性が保たれ、どのバージョンのモジュールを使用するかを直接コントロールできるようになります。
greetings.goというファイルを用意します。
touch greetings.go
以下のコードをgreetings.goファイルに貼り付け、ファイルを保存してください。
package greetings
import "fmt"
// Hello returns a greeting for the named person.
func Hello(name string) string {
// Return a greeting that embeds the name in a message.
message := fmt.Sprintf("Hi, %v. Welcome!", name)
return message
}
これがモジュールの最初のコードです。これは、あいさつを要求してきた発信者にあいさつを返すものです。次の記事で、この関数を呼び出すコードを書きます。
解説
greetings.go
package greetings
import "fmt"
// Hello returns a greeting for the named person.
func Hello(name string) string {
// Return a greeting that embeds the name in a message.
message := fmt.Sprintf("Hi, %v. Welcome!", name)
return message
}
このコードは、greetings
というパッケージを定義しています。このパッケージは、名前を受け取って挨拶のメッセージを生成する関数 Hello
を提供します。
コードの解説は以下の通りです:
package greetings
: この行はパッケージの宣言です。このパッケージの名前はgreetings
です。パッケージは関連するコードをグループ化するための単位であり、再利用可能なコードのまとまりを提供します。import "fmt"
: この行は、fmt
パッケージをインポートしています。fmt
パッケージは、標準入出力などのフォーマット関連の機能を提供します。func Hello(name string) string
: この行は、Hello
という名前の関数を定義しています。この関数は、文字列型のname
引数を受け取り、文字列型の結果を返します。message := fmt.Sprintf("Hi, %v. Welcome!", name)
: この行では、fmt.Sprintf
関数を使用して、name
変数の値を埋め込んだメッセージを生成しています。%v
は、フォーマット指定子であり、渡された引数の値を埋め込むために使用されます。生成されたメッセージはmessage
変数に代入されます。return message
: この行では、生成されたメッセージを返しています。
このコードは、greetings
パッケージ内のHello
関数を使用して、指定された名前に対して挨拶のメッセージを生成することができます。例えば、greetings.Hello("Alice")
を呼び出すと、"Hi, Alice. Welcome!"
というメッセージが返されます。このパッケージは他のプログラムからインポートされて使用することができます。
名前が大文字で始まる関数は、同じパッケージに含まれない関数から呼び出すことができます。これをGoでは exported name (エクスポートされた名前)と呼びます。エクスポートされた名前の詳細については、下記のGoツアー:「エクスポートされた名前」を参照してください。
おわりに
今日は、Golangでモジュールを作成する方法についてご紹介しました。次回はこのモジュールの使用方法についてご紹介します。
本記事で使用したコードは下記のリポジトリにあります。
何か質問や相談があれば、遠慮なくコメントしてください。また、エンジニア案件についても、いつでも相談にのっていますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント