はじめに
この文書は、モジュール内でのシンプルなGoパッケージの開発を示し、Goモジュール、パッケージ、コマンドを取得、ビルド、インストールするための標準的な方法であるgo toolを紹介します。
コードの整理
Goプログラムはパッケージに整理されています。パッケージは、同じディレクトリ内のソースファイルのコレクションであり、一緒にコンパイルされます。1つのソースファイルで定義された関数、型、変数、および定数は、同じパッケージ内の他のすべてのソースファイルから見えるようになります。
リポジトリは1つ以上のモジュールを含みます。モジュールは、関連するGoパッケージのコレクションであり、一緒にリリースされます。Goリポジトリは通常、リポジトリのルートにある1つのモジュールのみを含みます。そこにあるgo.mod
という名前のファイルは、モジュールパスを宣言します:モジュール内のすべてのパッケージのインポートパスプレフィックスです。モジュールは、そのgo.mod
ファイルを含むディレクトリ内のパッケージと、そのディレクトリのサブディレクトリを含み、次のgo.mod
ファイルを含む別のサブディレクトリまで続きます(あれば)。
コードをリモートリポジトリに公開する前にビルドする必要はないことに注意してください。モジュールは、リポジトリに属さずにローカルに定義できます。ただし、いつか公開するつもりでコードを整理することは良い習慣です。
各モジュールのパスは、そのパッケージのインポートパスプレフィックスとして機能するだけでなく、go
コマンドがそれをダウンロードする場所を示します。たとえば、モジュールgolang.org/x/tools
をダウンロードするには、go
コマンドがhttps://golang.org/x/tools
によって示されるリポジトリを参照します(詳細は[https://golang.org/cmd/go/#hdr-Remote_import_paths]を参照)。
インポートパスは、パッケージをインポートするために使用される文字列です。パッケージのインポートパスは、そのモジュール内のサブディレクトリと結合されたモジュールパスです。たとえば、モジュールgithub.com/google/go-cmp
は、ディレクトリcmp/
にあるパッケージを含みます。そのパッケージのインポートパスはgithub.com/google/go-cmp/cmp
です。標準ライブラリのパッケージにはモジュールパスプレフィックスがありません。
最初のプログラム
シンプルなプログラムをコンパイルして実行するには、まずモジュールパスを選択します(example/user/hello
を使用します)し、それを宣言するgo.mod
ファイルを作成します:
$ mkdir hello # Alternatively, clone it if it already exists in version control.
$ cd hello
$ go mod init example/user/hello
go: creating new go.mod: module example/user/hello
$ cat go.mod
module example/user/hello
go 1.16
$
Goソースファイルの最初のステートメントはpackage name
でなければなりません。実行可能なコマンドは常にpackage main
を使用する必要があります。
次に、そのディレクトリ内にhello.go
という名前のファイルを作成し、次のGoコードを含めます:
package main
import "fmt"
func main() {
fmt.Println("Hello, world.")
}
これで、go
ツールを使用してそのプログラムをビルドしてインストールできます:
$ go install example/user/hello
$
このコマンドはhello
コマンドをビルドし、実行可能なバイナリを生成します。その後、そのバイナリを$HOME/go/bin/hello
(またはWindowsの場合は%USERPROFILE%\go\bin\hello.exe
)としてインストールします。
インストールディレクトリはGOPATH
およびGOBIN
環境変数によって制御されます。GOBIN
が設定されている場合、バイナリはそのディレクトリにインストールされます。GOPATH
が設定されている場合、バイナリはbin
リストの最初のディレクトリのGOPATH
サブディレクトリにインストールされます。それ以外の場合、バイナリはデフォルトのGOPATH
のbin
サブディレクトリにインストールされます($HOME/go
または%USERPROFILE%\go
)。
go env
コマンドを使用して、将来のgo
コマンドのために環境変数のデフォルト値をポータブルに設定できます:
$ go env -w GOBIN=/somewhere/else/bin
$
go env -w
によって以前に設定された変数を解除するには、go env -u
を使用します:
$ go env -u GOBIN
$
go install
のようなコマンドは、現在の作業ディレクトリを含むモジュールのコンテキスト内で適用されます。作業ディレクトリがexample/user/hello
モジュール内にない場合、go install
は失敗する可能性があります。
便利なことに、go
コマンドは作業ディレクトリに対して相対的なパスを受け入れ、他のパスが指定されていない場合は現在の作業ディレクトリ内のパッケージをデフォルトとして使用します。したがって、作業ディレクトリ内では、次のコマンドはすべて同等です:
$ go install example/user/hello
$ go install .
$ go install
次に、プログラムを実行して動作することを確認しましょう。さらに便利なことに、バイナリを簡単に実行できるようにインストールディレクトリをPATH
に追加します:
# Windowsユーザーは/wiki/SettingGOPATHを参照してください
# %PATH%を設定するために。
$ export PATH=$PATH:$(dirname $(go list -f '{{.Target}}' .))
$ hello
こんにちは、世界。
$
ソース管理システムを使用している場合、今がリポジトリを初期化し、ファイルを追加し、最初の変更をコミットする良いタイミングです。このステップはオプションです:Goコードを書くためにソース管理を使用する必要はありません。
$ git init
Initialized empty Git repository in /home/user/hello/.git/
$ git add go.mod hello.go
$ git commit -m "initial commit"
[master (root-commit) 0b4507d] initial commit
1 file changed, 7 insertion(+)
create mode 100644 go.mod hello.go
$
go
コマンドは、対応するHTTPS URLを要求し、HTMLレスポンスに埋め込まれたメタデータを読み取ることによって、指定されたモジュールパスを含むリポジトリを見つけます(go help importpath
を参照)。多くのホスティングサービスは、Goコードを含むリポジトリのためにそのメタデータをすでに提供しているため、モジュールを他の人が使用できるようにする最も簡単な方法は、通常、そのモジュールパスをリポジトリのURLと一致させることです。
モジュールからパッケージをインポートする
``````bash
// Package morestrings implements additional functions to manipulate UTF-8
// encoded strings, beyond what is provided in the standard "strings" package.
package morestrings
// ReverseRunes returns its argument string reversed rune-wise left to right.
func ReverseRunes(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}
`
私たちのReverseRunes
関数は大文字で始まるため、エクスポートされたものであり、私たちのmorestrings
パッケージをインポートする他のパッケージで使用できます。
go build
を使用してパッケージがコンパイルされることを確認しましょう:
$ cd $HOME/hello/morestrings
$ go build
$
これにより出力ファイルは生成されません。代わりに、コンパイルされたパッケージはローカルビルドキャッシュに保存されます。
``````bash
package main
import (
"fmt"
"example/user/hello/morestrings"
)
func main() {
fmt.Println(morestrings.ReverseRunes("!oG ,olleH"))
}
`
``````bash
$ go install example/user/hello
`
プログラムの新しいバージョンを実行すると、新しい逆さまのメッセージが表示されるはずです:
$ hello
Hello, Go!
リモートモジュールからパッケージをインポートする
インポートパスは、GitやMercurialなどのリビジョン管理システムを使用してパッケージのソースコードを取得する方法を説明できます。go
ツールは、この特性を使用してリモートリポジトリからパッケージを自動的に取得します。たとえば、プログラムでgithub.com/google/go-cmp/cmp
を使用するには:
package main
import (
"fmt"
"example/user/hello/morestrings"
"github.com/google/go-cmp/cmp"
)
func main() {
fmt.Println(morestrings.ReverseRunes("!oG ,olleH"))
fmt.Println(cmp.Diff("Hello World", "Hello Go"))
}
外部モジュールに依存関係があるため、そのモジュールをダウンロードし、go.mod
ファイルにそのバージョンを記録する必要があります。go
mod tidy
コマンドは、インポートされたパッケージの不足しているモジュール要件を追加し、もはや使用されていないモジュールの要件を削除します。
$ go mod tidy
go: finding module for package github.com/google/go-cmp/cmp
go: found github.com/google/go-cmp/cmp in github.com/google/go-cmp v0.5.4
$ go install example/user/hello
$ hello
Hello, Go!
string(
- "Hello World",
+ "Hello Go",
)
$ cat go.mod
module example/user/hello
go 1.16
require github.com/google/go-cmp v0.5.4
$
モジュールの依存関係は、GOPATH
環境変数によって示されるディレクトリのpkg/mod
サブディレクトリに自動的にダウンロードされます。特定のバージョンのモジュールのダウンロードされた内容は、そのバージョンをrequire
する他のすべてのモジュールで共有されるため、go
コマンドはそれらのファイルとディレクトリを読み取り専用としてマークします。すべてのダウンロードされたモジュールを削除するには、-modcache
フラグをgo clean
に渡すことができます:
$ go clean -modcache
$
テスト
Goには、go test
コマンドとtesting
パッケージで構成された軽量のテストフレームワークがあります。
テストは、_test.go
で終わる名前のファイルを作成し、TestXXX
という名前のfunc (t *testing.T)
シグネチャを持つ関数を含めることによって書きます。テストフレームワークは、そのような関数をそれぞれ実行します。関数がt.Error
やt.Fail
のような失敗関数を呼び出すと、テストは失敗したと見なされます。
``````bash
package morestrings
import "testing"
func TestReverseRunes(t *testing.T) {
cases := []struct {
in, want string
}{
{"Hello, world", "dlrow ,olleH"},
{"Hello, 世界", "界世 ,olleH"},
{"", ""},
}
for _, c := range cases {
got := ReverseRunes(c.in)
if got != c.want {
t.Errorf("ReverseRunes(%q) == %q, want %q", c.in, got, c.want)
}
}
}
`
次に、go test
でテストを実行します:
$ cd $HOME/hello/morestrings
$ go test
PASS
ok example/user/hello/morestrings 0.165s
$
go help test
を実行し、テストパッケージのドキュメントを参照して詳細を確認してください。
次は何ですか
golang-announceメーリングリストに登録して、新しい安定版のGoがリリースされたときに通知を受け取ります。
明確で慣用的なGoコードを書くためのヒントについては、Effective Goを参照してください。
言語を正しく学ぶために、A Tour of Goを受けてください。
Go言語とそのライブラリおよびツールに関する詳細な記事のセットについては、ドキュメントページを訪れてください。
ヘルプを得る
リアルタイムのヘルプが必要な場合は、コミュニティ運営のgophers Slackサーバーで役立つゴファーに尋ねてください(こちらから招待を取得)。
Go言語の議論のための公式メーリングリストはGo Nutsです。
バグを報告するには、Go issue trackerを使用してください。