Slide 1

Slide 1 text

What's new in Go 1.21? シアラナ Go 1.21 リリースパーティ & GopherCon 2023 報告会 2023-10-31

Slide 2

Slide 2 text

自己紹介 ● シアラナ ○ X: cia_rana / Zenn: koya_iwamura ● 株式会社アプリボット ○ 新規プロジェクトでサーバーサイドエンジニア ● Goの記事書いたり、コントリビュートしたり

Slide 3

Slide 3 text

リリースおめでとうございます 🎉

Slide 4

Slide 4 text

Goのバージョンの表記方法 ● メジャーリリースの一番最初のバージョンの末尾にパッチバージョンが つくようになった

Slide 5

Slide 5 text

packageの初期化順がspecに明示された ● importしているpackageをpackage名の昇順でソートして、順番に初期化する ● importしているpackageより、importされているpackageのほうが先に初期化される ● すでに初期化されたpackageは再度初期化されない

Slide 6

Slide 6 text

loopvar ● forループでループ変数をクロージャ内で使用すると、ループを抜けたときのループ変数 がループ全体で使われている、直感的ではない挙動があった ● Go1.20までは一旦別の変数に退避する必要があった ● Go1.21では実験版として環境変数GOEXPERIMENT=loopvarを指定して ループ全体で使われなくなるできる ● Go1.22で本採用される(かも) ● 後方互換性のない変更で悪影響の出るコードもあるかもしれないので、 検知するツールがいくつか用意されている ● 詳しくはThe Go Blog『Fixing For Loops in Go 1.22』参照

Slide 7

Slide 7 text

ビルトイン関数 max, min ● 引数の中から最大・最小の値を返す ● 3つ以上の引数もOK ● 引数の型はorderedである必要がある ● sliceはそのまま渡せない(代わりにpackage slicesを使う)

Slide 8

Slide 8 text

ビルトイン関数 clear ● map, sliceをクリアする ● mapは要素数を0にする ● sliceは要素それぞれをゼロ値にする

Slide 9

Slide 9 text

PGOの本格導入 ● PGO = Profile-Guided Optimization ● 実行時にリソースの利用状況を収集し、次回のコンパイル最適化に活かす手法 ○ Go1.21時点では、インライン展開、devirtualizationに効いてくる ● Go 1.20ではパブリックプレビュー版だったが、今回で正式にリリースとなった ● package mainにdefault.pgoがあれば自動的に利用される ● -pgoフラグで読み込むファイルを指定できる ○ デフォルトは-pgo=auto ○ オフにするには-pgo=off ● 詳しくは The Go Blog『Profile-guided optimization in Go 1.21』参照

Slide 10

Slide 10 text

PGOにおけるdevirtualization ● 通常のコンパイルではinterfaceのmethodをstructのmethodに置換する ● PGOでは特定のstructに置換できるとは限らないので、型アサーションする

Slide 11

Slide 11 text

スタックトレースの出力 ● スタックトレースを出力する際に、 呼び出し先から100フレーム分出力していたのが、 呼び出し先から50フレーム、呼び出し元から50フレーム出力するようになった

Slide 12

Slide 12 text

panic, recoverの挙動 ● panicをrecoverする際に、recoverの戻り値がnilではないことが 保証されるようになった ● panicにnilを渡すと、recoverの戻り値は*runtime.PanicNilErrorになる ● GODEBUG=panicnil=1でGo1.20以前の挙動に戻せる

Slide 13

Slide 13 text

log/slog, testing/slogtest package ● 構造化ログやログレベルを設定できるロガー ● interface Handlerを実装して出力方法を拡張可能 ● 拡張したHandlerをテストするslogtest.TestHandlerも用意されている ● 詳しくはThe Go Blog『Structured Logging with slog』参照 ● 公式でExampleも用意されている

Slide 14

Slide 14 text

cmp package ● func Compare ○ 比較結果を-1, 0, +1で返す ● func Less ○ 比較結果をbool値で返す ● type Ordered ○ 比較可能なunderlying typeを含むプリミティブ型を集めたconstraint ○ ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64 | ~string ● package github.com/google/go-cmpとは別物

Slide 15

Slide 15 text

slices package ● func BinarySearch, BinarySearchFunc ○ 昇順にソートしたsliceから特定の要素を二分探索 ○ sort.Searchより直感的に書ける

Slide 16

Slide 16 text

slices package ● func Compact ○ 連続する等しい要素を1つにしたsliceを返す ○ 元のsliceは書き換えない ○ lenは変わるが、capは変わらない

Slide 17

Slide 17 text

slices package ● func Sort ○ sliceをソートする ○ sort.Sortより直感的に書けて、かつ実行速度が速い(らしい) ○ 元のsliceを書き換える

Slide 18

Slide 18 text

slices package ● func Reverse ○ sliceを反転する ○ package sortを使うより大分楽に書ける ○ 元のsliceを書き換える

Slide 19

Slide 19 text

slices package ● func Clip ○ capをlenまで縮退し、無駄なcapを削減 ● func Compare ○ 2つのsliceを比較 ○ 要素の大小やlenによって-1, 0, +1を返す ● func Contains ○ 指定した要素が含まれるかチェック ● func Insert ○ i番目に要素を挿入 ○ 元のsliceを書き換えない ● func IsSorted ○ 昇順にソートされているかチェック ● func Replace ○ iからj番目の要素を可変長引数の要素で置換 ○ 元のsliceを書き換えない ● func Max, Min ○ sliceの要素の中で最大値、最小値を求める

Slide 20

Slide 20 text

maps package ● func Clone ○ Shallow copy ● func Copy ○ 一方のmapのkey-valueを、もう一方のmapに追加 ● func DeleteFunc ○ 特定の要素を削除 ● func Equel ○ 2つのmapのkey-value同士を比較し、等しいかをチェック ● func Keys, ValuesはGo1.22で導入予定のiterで使用用途的に代替できるため見送り

Slide 21

Slide 21 text

Multipath TCPのサポート ● Multipath TCPとは ○ 単一のTCPコネクションに対し、複数のネットワークパスでデータを送受信すること で、スループットや安定性を向上させる技術 ● 今回のリリースでは、マルチパスTCP対応のLinuxカーネルのみサポート

Slide 22

Slide 22 text

net/http ResponseController.EnableFullDuplex ● http/1において、リクエストボディを読み込み中に、 レスポンスボディを書き込むことができるようになった ● ちなみにWebsocketやhttp/2ではデフォルトで使用できる機能

Slide 23

Slide 23 text

regexp Regexp.MarshallText, UnmarshallText ● 構造体RegexpがメソッドMarshallTextとUnmarshallTextを実装した ● 例えば、JSONのフィールドとして正規表現を読み書きできるようになる

Slide 24

Slide 24 text

runtime/metrics package ● GCの挙動が追いやすくなるメトリクスが追加された ○ /gc/gogc:percent ■ GOGCやruntime/debug.SetGCPercentで設定された値(default: 100) ○ /gc/gomemlimit:bytes ■ GOMEMLIMITやruntime/debug.SetMemoryLimitで設定された値(default: math.MaxInt64) ○ /gc/heap/live:bytes ■ 直近のGCサイクルでマークされたヒープ ○ /gc/scan/globals:bytes ■ スキャン可能なグローバル変数 ○ /gc/scan/heap:bytes ■ スキャン可能なヒープ ○ /gc/scan/stack:bytes ■ 直近のGCサイクルでスキャンされたスタック ○ /gc/scan/total:bytes ■ /gc/scanの合計

Slide 25

Slide 25 text

sync OnceFunc, OnceValue, OnceValues ● 構造体Onceを利用した頻出パターンを関数化した OnceFunc, OnceValue, OnceValuesが追加された ● struct Once ○ OnceのメソッドDoを一度だけ実行することを保証する ● func OnceFunc ○ 引数に渡された関数を一度だけ実行することを保証する ○ Onceの簡略化バージョン ● func OnceValue ○ 引数に渡された関数を一度だけ実行することを保証し、 何度呼び出しても毎回同じ戻り値を 1つ返す ○ OnceFuncの戻り値ありバージョン ● func OnceValues ○ 引数に渡された関数を一度だけ実行することを保証し、 何度呼び出しても毎回同じ戻り値を 2つ返す ○ OnceValueの戻り値2つバージョンで、errorを返す場合などに使う

Slide 26

Slide 26 text

Appendix ● Go1.21 New Features ○ 今回紹介できなかったGenericsの型推論やslices package、 goコマンドのフラグ等々について書いているのでぜひ 🙌 ● [Blog] Backward Compatibility, Go 1.21, and Go 2 ● [Doc] Go, Backwards Compatibility, and GODEBUG ● [Blog] Forward Compatibility and Toolchain Management in Go 1.21 ● [Blog] Perfectly Reproducible, Verified Go Toolchains ● [Doc] Go Toolchains ● [Blog] WASI support in Go