Overview
Go 1.18 がリリースされて目玉の機能である Generics について一通り触ってみました。
実装に入門する
公式の Go の Generics のチュートリアルを参考に実装してみました。
またより詳しい入門には以下の公式のブログがあります。
サンプル実装
map の key を取り出す
ありがちな実装ですが map から key のみを取り出したり、value だけを取り出したり、といった処理を書くことができます。
今までは取り出した値の型ごと(int, string) に Keys だったり Values の実装が必要でしたが、これからは以下のようにかけます。
func Keys[T comparable](m map[T]interface{}) []T { keys := make([]T, 0, len(m)) for k := range m { keys = append(keys, k) } return keys }
簡単に再実装をしてみましたが、これは https://pkg.go.dev/golang.org/x/exp@v0.0.0-20220325121720-054d8573a5d8/maps#Keys に既に実装されてました。
スライスのシャッフル処理
func shuffle[T comparable](s []T) { rand.Seed(10) // seed は任意の自然数 rand.Shuffle(len(s), func(i, j int) { s[i], s[j] = s[j], s[i] }) }
ref: https://go.dev/play/p/OToYELH1S-1
その他使えそうなユースケケースについて
以下でまとめたことがありましたが、API クライアントの共通化処理において Setter っぽい実装で Getter を書くというユースケースにおいては Generics を使うことができそうだなと思いました。
golang.org/x/exp 配下のパッケージついて
今まで型ごとに冗長な実装をせざる得なかった、slice や map の操作については以下の2つの packages にまとまっています。
golang.org/x/exp/maps
golang.org/x/exp/slices
ありがちな sort なども slices パッケージに実装されています。
まとめ
以下のブログにある通り、これを使ってもっとゴリゴリコードを抽象化したり関数型っぽい実装が増えることもあるのかもしれませんが当面はユースケースを絞って適用していく、くらいのところでまずは留めておこうかなと思っています。特にプロダクションで書く場合には。