はじめに
Go 1.23リリース連載 の4本目です。
Go 1.23の目玉機能でもあるイテレータの導入に合わせて、slices
パッケージと maps
パッケージにも新たな関数が追加されました。
本記事では新たに追加された関数をサンプルコードとともに紹介します。
イテレータの詳細については、連載3本目の記事「Go 1.23リリース連載 range over funcとiterパッケージ」を参照してください。
関連する Issues
今回のアップデートは、range over function(#61405)の追加に伴うものとなります。iter
パッケージの追加(#61897)をはじめとする標準ライブラリの一連のアップデートの内の1つとして位置付けられています。
slices
と maps
に関する Issue は次の2つです。
実行環境
Goのバージョンは go1.23rc2
を使用しています。
$ go version |
サンプルコードはこちらのリポジトリで公開しています。
https://github.com/rhumie/tech-blog-go-1.23-feature
slices
関数名 | 説明 |
---|---|
All |
スライスのインデックスと要素に対するイテレータを返却します |
Values |
スライスの要素に対するイテレータを返却します |
Backward |
スライスの要素に対する逆方向のイテレータを返却します |
Collect |
イテレータからスライスを生成し、返却します |
AppendSeq |
イテレータからスライスに対して要素を追加します |
Sorted |
イテレータからスライスを生成し、ソートした上でスライスを返却します |
SortedFunc |
イテレータからスライスを生成し、指定された関数をもとにソートした上でスライスを返却します |
SortedStableFunc |
イテレータからスライスを生成し、指定された関数をもとにソート(安定ソート)した上でスライスを返却します |
Chunk |
スライスを指定された要素数のサブスライスのイテレータとして返却します |
All
スライスのインデックスと要素に対するイテレータを返却します。
▼ サンプルコード
package main |
▼ 実行結果
0: a |
Values
スライスの要素に対するイテレータを返却します。
▼ サンプルコード
package main |
▼ 実行結果
a |
Backward
スライスの要素に対する逆方向のイテレータを返却します。
▼ サンプルコード
package main |
▼ 実行結果
2: c |
Collect
イテレータからスライスを生成し、返却します。
▼ サンプルコード
package main |
▼ 実行結果
0: a |
AppendSeq
イテレータからスライスに対して要素を追加します。
▼ サンプルコード
package main |
▼ 実行結果
0: a |
Sorted
イテレータからスライスを生成し、ソートした上でスライスを返却します。
▼ サンプルコード
package main |
▼ 実行結果
0: a |
SortedFunc
イテレータからスライスを生成し、指定された関数をもとにソートした上でスライスを返却します。
▼ サンプルコード
package main |
▼ 実行結果
0: {Alice 20} |
※ 次に説明する SortedStableFunc
と異なり、安定ソートではないため、Aliceの順番は変わる可能性があります。
SortedStableFunc
イテレータからスライスを生成し、指定された関数をもとにソートした上でスライスを返却します。SortedFunc
と異なり、安定ソート(同等なデータのソート前の順序が、ソート後も保存される)を行います。
▼ サンプルコード
package main |
▼ 実行結果
0: {Alice 20} |
※ SortedFunc
とは異なり、Aliceの順番は保証されます。
Chunk
スライスを指定された要素数のサブスライスのイテレータとして返却します。
▼ サンプルコード
package main |
▼ 実行結果
[a b] |
maps
Go 1.21にて正式導入が見送られていた(#61538) Keys
や Values
が、イテレータの導入に伴い、正式に標準ライブラリに加わりました。
関数名 | 説明 |
---|---|
All |
マップのキーとバリューに対するイテレータを返却します |
Keys |
マップのキーに対するイテレータを返却します |
Values |
マップのバリューに対するイテレータを返却します |
Insert |
イテレータからマップに対してキー・バリューのペアを追加します |
Collect |
イテレータからマップを生成し、返却します |
All
マップのキーとバリューに対するイテレータを返却します。
イテレータの順序は指定されず、呼び出しごとに異なる可能性があります。
▼ サンプルコード
package main |
▼ 実行結果
10: ten |
※順序は実行するたびに変わります。
Keys
マップのキーに対するイテレータを返却します。
▼ サンプルコード
package main |
▼ 実行結果
100 |
※順序は実行するたびに変わります。
Values
マップのバリューに対するイテレータを返却します。
▼ サンプルコード
package main |
▼ 実行結果
ten |
※順序は実行するたびに変わります。
Insert
イテレータからマップに対してキー・バリューのペアを追加します。
マップ内に既にキーが存在する場合は上書きされます。
▼ サンプルコード
package main |
▼ 実行結果
10: zehn |
※順序は実行するたびに変わります。
Collect
イテレータからマップを生成し、返却します。
▼ サンプルコード
package main |
▼ 実行結果
100: hundred |
※順序は実行するたびに変わります。
unique (おまけ)
これまで紹介した slices
や maps
とは毛色が異なりますが、Go1.23で新たに追加された unique
パッケージ(#62483)についても紹介します。
これは、サードパーティのパッケージの go4org/intern にインスパイアされたものであり、インターン化(interning)といわれる機構によりメモリを節約できます。1
インターン化という言葉を聞き馴染みない方もいるかもしれませんが、Wikipediaでインターン化を調べると「新しいオブジェクトを作成する代わりに、同じ値のオブジェクトを再利用することである(意訳)」と説明されています。
interning is re-using objects of equal value on-demand instead of creating new objects
実際にサンプルコードを見てみましょう。
▼ サンプルコード
package main |
▼ 実行結果
Before: |
unique
パッケージの Make
と Value
を利用して、文字列のインターン化を行なってますが、実行前は string
を構成する基底バイト列(underlying bytes)のメモリアドレスが異なるのに対し、実行後は全て同じになっていることが確認できます。
特定のシナリオにおいてプログラムのパフォーマンスの最適化が必要な場合に有効となります。
おわりに
slices
と maps
、そして unique
を紹介しました。
range over func とイテレータの登場に合わせて、非常に注目度の高いアップデートではないかと思います。
次回は、辻さんによる text/template の紹介です。
- 1.他の言語を見てみると、Javaにおいては
String.Intern()
、Pythonにおいてはsys.intern()
という形で同様の機能が提供されています。 ↩