概要
Goのジェネリクス1を試そうと思うと、以前は go2go playground で試すか、開発ブランチを自分でビルドする必要があったようですが、2021/06現在では比較的簡単に手元で試せるようになっています。
下記では go1.17beta1 を使っていますが、 2021/07/13現在では go1.17rc1 がリリースされていますので、そちらをお使いください。。
簡単に説明すると、次のような手順になります:
- 公式ダウンロードサイト から go1.17beta1 のバイナリ配布物を取得し、インストールする
-
export GOFLAGS="-gcflags=-G=3"
する - ジェネリクスの記述が入った任意のコードを
go build
する
Goのジェネリクスの書き方がよくわからなければ、配布物に同梱の $GOROOT/test/typeparam/
配下に参考になるソースコードが多数置かれています。
お断り
Go 1.71beta1 におけるジェネリクスはまだデフォルトで無効化された実験的なものです。正しいソースコードのはずなのにコンパイルできない、動作がおかしい等の不具合にあたる可能性もありますので、ご利用は自己責任でお願いします。
詳細
ここからは具体的に見ていきます。
手順1: go1.17beta1 のインストール
go1.17beta1 は 公式ダウンロードサイト の最下部のやや上、やや見つけにくいですが、 go1.17beta1
と書かれたところにあります。(2021/06現在。すでにGA版の 1.17.x がリリースされているのであれば、そちらを使えばOK)
掲載されている sha256 値とダウンロードしたファイルのsha256値が一致することを確認します(一致しない場合はファイルが壊れています)。ここでは darwin 版バイナリ(非pkg)をダウンロードしたものとします。
$ sha256sum go1.17beta1.darwin-amd64.tar.gz
50046983ccd66180d1b6fbf39b4e5acb61dd08f1b53803661d86b60ba304bf80 go1.17beta1.darwin-amd64.tar.gz
続いてダウンロードしたアーカイブファイルを /usr/local/go に展開します。
$ sudo tar zxvf /path/to/go1.17beta1.darwin-amd64.tar.gz -C /usr/local
go/
go/api/
go/AUTHORS
go/bin/
go/codereview.cfg
go/CONTRIBUTING.md
go/CONTRIBUTORS
go/doc/
go/lib/
go/LICENSE
(以下略)
アーカイブは go というディレクトリのみを含んでいるので、 -C /usr/local
をつければ /usr/local/go として展開されます。
最後に、/usr/local/go/bin
にPATHを通します。
.bashrc 等、お使いの対話シェルの初期化ファイルに所定の記法で PATH を通します。
例えばbashの場合は次のような行を足せば良いです。
PATH=/usr/local/go/bin:$PATH
ターミナルやシェルを起動しなおすか、上記の行をコマンドラインとして実行すると、当該シェルのセッションで /usr/local/go/bin 配下のコマンドを実行できるようになります。
これで Go 1.17beta1 のインストールが完了しました。
手順2: export GOFLAGS="-gcflags=-G=3"
する
-gcflags=-G=3
はコンパイル時にGoのコンパイラに対してジェネリクスを有効にするよう指示するフラグです。
コマンドラインであれば go build -gcflags=-G=3
と指定すればジェネリクスの文法を含んだGoソースコードをコンパイルできます。
そして、環境変数 GOFLAGS にこれを指定することで、コマンドラインでの指定を省略できます。
bash系であればこれはそのまま実行しても良いですし、継続的に有効にしたいのであれば .bashrc などに追記すると良いでしょう。
手順3: ジェネリクスの記述が入った任意のコードを go build
する
例えば次のようなコードをコンパイルしてみましょう。
package main
import (
"fmt"
)
type Ordered interface {
type int, float64
}
func min[T Ordered](x, y T) T {
if x < y {
return x
}
return y
}
func main() {
a, b := 2, 3
c, d := 2.5, 3.8
fmt.Println(min(a, b))
fmt.Println(min(c, d))
}
現行のGoでは明らかに通らないシンタックスを利用してジェネリックな min (2つの引数のうち小さいほうを返す) 関数が書かれています。
$ go build -o a.out && ./a.out
2
2.5
コンパイルと実行ができました。もちろん go run main.go
などと run しても構いません。
本記事にしたがってGoをインストールした環境であれば、 /usr/local/go/test/typeparam
配下に様々なジェネリクスの利用例がありますので、色々と実験してみると理解が深まると思います。
まとめ
- ジェネリクスが導入された Go 1.17beta1 はすでに簡単に利用可能だよ
- ジェネリクスを有効化してコンパイルするには
go build -gcflags=-G=3
を指定すればいいよ - ジェネリクスのお手本は
/usr/local/go/test/typeparam
たくさんにあるよ
記事は以上になります。最後までお読みいただき、ありがとうございました。
誤り等ありましたらコメントや編集リクエストでお知らせください。
-
Go でジェネリクスを実現する機能は Type Parameter と呼ばれていますが、ここではジェネリクスと統一しました。 ↩