Go言語のバージョン1.18からGenericsが入りました。
自分がGo言語を使う範囲では、汎用的な関数を書くこともないし、関数の記述も長くなるので、Genericsを使うことはないかなと思っていました。
便利な機能が追加されていた
とは言え、Genericsを全く知らないのも何だし、雰囲気だけでも見ておこうと調べたところ、Generics導入に合わせて、実験的扱いではありますがslice
とmap
関連のモジュールが追加されていました。
いわゆる他の言語によくある、配列やマップの便利メソッドです。
例えば、下記のJavaScriptの様に、マップのキーをソートした配列を取得したいとします。
JavaScript
const data = { "B": 2, "A": 1, "C": 3, } const keys = Object.keys(data).sort(); console.log(keys);
[ 'A', 'B', 'C' ]
これをGo言語の新しいモジュールで書くと下記のようになります。
Go言語
package main import ( "fmt" "golang.org/x/exp/maps" "golang.org/x/exp/slices" ) func main() { data := map[string]int{ "B": 2, "A": 1, "C": 3, } keys := maps.Keys(data) slices.Sort(keys) fmt.Printf("%+v\n", keys) }
[A B C]
この機能欲しかったんですよ!
今までGenerics無しで同じ事をしようとすると、愚直にfor文使って自分で書くしかなかったのですが、これで他の言語のようにスッキリと書けます。
配列・マップの自分自身が書き換わるので、他の言語の様にメソッドチェーンでは書けないのですが、速度・効率のため新たな配列・マップを生成して欲しくないケースもあるので、Go言語にはこの書き方があっているのかなと思います。
自分自身を書き換えるのが嫌な場合は、配列・マップのコピーを生成する関数も用意されているので、それを使ってコピーを書き換えれば済みますし。
やっぱりGenericsは必須だった
この様に、自分でGenericsを書くことはなくても、今後Genericsを利用する場面は増えていき必須になるんだろうなと思いました。
今はfilter
やforEach
的な関数がないので、今後色んな関数が実装され、標準ライブラリに昇格するのを期待してます。
また、Go言語の並行処理は便利でよく使うのですが、ゴルーチンやチャネルを使って毎回同じようなコードを1から書いているので、Genericsを使ったタスクパイプライン(RxGoをGenerics化したようなもの)の標準ライブラリが登場して欲しいですね。