今回は、ランダムな数(乱数)を表示するプログラムを通して、Goで多彩な機能を使うためのパッケージとインポートについて学びます。
ランダムな数を表示する
Goのプログラムは初期状態だと大したことはできませんが、世の中に存在するパッケージを取り込むことでやれることが増えます。例えばゲームでもよく使う乱数は、rand
パッケージが提供しています。使ってみましょう。以下のプログラムで0から5までのランダムな数を表示できます。
package main
import (
"fmt"
"math/rand/v2"
)
func main() {
fmt.Println(rand.N(6))
}
結果は毎回変わるので、以下は一例です。たくさん実行してみてください。
$ go run .
3
$ go run .
0
何だか遊びに繋がりそうな気がしてきましたか?
[経験者向け] シード値・ランダマイズ
Goの math/rand/v2
パッケージのグローバル関数で生成される乱数列は再現性がありません(ランダマイズされています)。その方がセキュリティ的に好ましいためです。
ゲームではシード値を固定して再現性を持たせる使い方もよく行います。例えばリプレイですべての数列を保存する代わりにシード値だけで再現できるようにしたり、マインクラフトでシード値だけ共有すれば同じワールドで遊べるようにしたり、かの有名なドルアーガの塔の逸話のように、ゲームデザインそのものに組み込むこともあります。
Goでシード値を固定するには rand.NewPCG 関数や rand.NewChaCha8 関数にシード値を渡して乱数生成器を作成します。
パッケージとインポート文
パッケージを利用するにはまずインポート(取り込み)が必要です。このプログラムは、fmt
と math/rand/v2
をインポートしています。
import (
"fmt"
"math/rand/v2"
)
()
でくくられていますが、これは2つのインポート文と同じ意味です。
import "fmt"
import "math/rand/v2"
"fmt"
や "math/rand/v2"
はインポートパスと呼ばれる、パッケージの「場所」を表す概念です。後述しますがインターネット上の場所を指定することでインターネットからパッケージを取り込むことができます。
インポートしたら、プログラムの中で fmt.
や rand.
のようにパッケージ名にドット .
をつけて、パッケージが提供する機能を利用します。
"fmt"
と fmt
のようにインポートパスとパッケージ名が同じ場合もありますが、"math/rand/v2"
と rand
のように異なる場合もあります。この辺は厳密な決まりはないので都度指示に従いましょう。
パッケージとの付き合い方
Goにはたくさんのパッケージが付属しており、またインターネット上でも誰でも自由にパッケージを公開できるため、無数のパッケージが世の中には存在しています。これらは使い方を暗記してからじゃないとプログラミングできないかというと全くそんなことはなく、熟練者でも誰しもが都度使い方を調べながらプログラミングをしています。プログラマーの時間の大半はむしろそういった調べる時間に充てられているとさえ揶揄されることもしばしばあります。そういうわけなので、覚えるよりまずは調べることを意識してプログラミングに取り組むと良いでしょう。
この本はGoやEbitengineの機能ごとにページを分けているため、機能の使い方を都度調べるのにも役に立つ構成になっているはずです。
ドキュメントを読む
公開された世界中のあらゆるGoパッケージのドキュメントがpkg.go.devというサイトにまとまっています。Goでプログラミングをする上で欠かせないものなので、いずれ未知のパッケージに触れようと思ったらぜひ参照してください。
ただ、基本すべて英語なので、ブラウザの拡張機能などで翻訳しながら読むとよいでしょう。
rand.N関数のドキュメント。ものによってはサンプルプログラムもついてくる。
まとめ
- パッケージを利用することでさまざまな機能が使えるようになる。
- パッケージを利用するにはまずインポートパス(
math/rand/v2
など)を指定してインポートする。 -
パッケージ名(
rand
など)を使ってパッケージの機能を呼び出す。 - https://pkg.go.dev は超便利。ブックマークしておこう。
詳しい解説
インポートパスとパッケージ名の詳細
原則的に、インポートパスが github.com/
などのインターネットのドメイン名から始まる場合、そのパッケージはサードパーティー(第三者提供の)パッケージであり、インターネット上からダウンロードされます。そうでないものはGo本体に付属する公式製の標準パッケージで、ダウンロードなしでいきなり使うことができます。サードパーティーパッケージは後ほど解説する「モジュール」とも関連が深いので、またいずれ。
インポートパスはパッケージの場所を示す文字列です。スラッシュで区切られており、区切られた最後の要素が一般的にパッケージ名になりますが、絶対ではありません。
[経験者向け] インポートパスとパッケージ名の慣習
-
/v2
で終わるパッケージは、バージョン2を示しています。メジャーバージョンが変わることは互換性がないことを意味するので、Goではバージョン2以上はインポートパスにメジャーバージョンを含めることで、バージョン1以下とは別のパッケージとして区別することが推奨されています。 - 他にも
github.com/mattn/go-sqlite3
(パッケージ名はsqlite3
)のように、作者の都合でインポートパスとパッケージ名を決めることができます。