Go 1.20.0 が先日リリースされた。
気になる機能はいくつかあるが、職場にて math/rand パッケージが話題に上がっていたのでチェックしてみた。
ちなみに arena パッケージの実験的サポート、errors.Join 、context.Context の Cause あたりが気になる機能である。
Homebrew でのサポート時間差問題
例の如く Homebrew で最新バージョンがインスコできるまで若干ラグが生じる。(1wくらい?)
プログラミング言語処理系とかCLIツールは Homebrew 管理で統一したいので、我慢するかpkgでインスコするかどちらかを選ぶ必要があるか?と思ったが、Dockerイメージを使うという選択肢があることに気がついた。
Docker 上で実行
1.20.0 タグの付いたイメージを使って、コンテナ上で実行すればいいじゃない!
docker run
して、
docker run -itd --name golang1.20.0 golang:1.20.0-alpine3.16
コンテナ上でmain.goを作る。
docker exec -it golang1.20.0 /bin/sh # 以下はコンテナ上で実行 vi main.go
package main import ( "math/rand" ) func main() { println(rand.Intn(10)) }
何度か実行してみる。
go run main.go 2 go run main.go 7 go run main.go 0 go run main.go 4 go run main.go 6 go run main.go 5
ちゃんと値がばらけている。
タネを生成したいときはどうするの
rand.New で生成できるみたい。
ドキュメントはちゃんと読めていないが、Exampleをもとにプログラムも書いてみた。
package main import ( "math/rand" ) func main() { r := rand.New(rand.NewSource(99)) println(r.Intn(10)) }
実行してみると固定値が返る。
go run main.go 7 go run main.go 7 go run main.go 7 go run main.go 7
ちなみに rand.Seed は非推奨になっている。
確かにグローバルに書き換わるのは安心して使えないので、スコープの閉じた生成器を用意するのが良いよね。
そういえば
Goを書きたての時に、タネが固定値であることを知らず、何度実行しても同じ値が返ってくる!とハマった気がする。
あの時の自分のように悩む人が今後はいなくなりますね。