Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What's new in Go 1.20?

syumai
February 21, 2023

What's new in Go 1.20?

Go 1.20 リリースパーティーの発表資料です
* https://gocon.connpass.com/event/273096/

関連するおすすめ記事
* https://zenn.dev/koya_iwamura/articles/bb9b590b57d825
* https://future-architect.github.io/articles/20230123a/

syumai

February 21, 2023
Tweet

More Decks by syumai

Other Decks in Programming

Transcript

  1. 自己紹介 syumai Go Documentation 輪読会 / ECMAScript 仕様輪 読会 主催

    株式会社ベースマキナで管理画面のSaaS を開発中 Go でGraphQL サーバー (gqlgen) や TypeScript で フロントエンドを書いています Twitter: @__syumai Website: https://syum.ai
  2. スライスから配列への変換 Go 1.17 でスライスを配列のポインタに変換出来るようになった スライスを配列に変換したい時は、まず配列のポインタに変換した 上でデリファレンスする必要があった Go 1.20 では、スライスを直接配列に変換出来るようになった s

    := []int{1, 2, 3} a1 := *(*[3]int)(s) // Go 1.17 までの書き方 a2 := [3]int(s) // Go 1.20 からの書き方 a3 := [2]int(s) // OK: 変換後の配列の方が変換前のスライスより短い a4 := [4]int(s) // NG: 変換後の配列の方が変換前のスライスより長い (panic) https://go.dev/play/p/Mqt9E7iYqfT
  3. unsafe package への変更 SliceData / StringData 関数の追加 slice / string

    から、基底配列の開始位置へのポインタを取得する String 関数の追加 基底配列の開始位置へのポインタと、長さから文字列を生成する // String 関数の例 b := []byte("abc") s := unsafe.String(&b[0], 3) // byte へのポインタと長さから文字列を生成 fmt.Println(s) // abc b[2] = byte('a') fmt.Println(s) // aba => byte slice から作った文字列を後から変更可能 https://go.dev/play/p/WrcSLoRYA-n
  4. comparable 制約の変更 比較可能な型(comparable types) が、comparable 制約を満たすように なった。 これまでは、基本的なインタフェース(basic interface) 型のような、比

    較可能だが実行時にpanic する可能性のある型はcomparable 制約を満 たさない仕様となっていた。 type StringMap[T comparable] map[T]string var m StringMap[any] // any はcomparable 制約を満たすのでOK " 満たす"(satisfy) と" 実装する"(implements) の定義が異なる点に注意 詳細についてはNobishii さんの記事の解説を参照ください https://zenn.dev/nobishii/articles/basic-interface-is-comparable
  5. Windows Windows 7, 8, Server 2008 / Server 2012 で動くのはGo

    1.20 が最後 Go 1.21 からはWindows 10 / Server 2016 以上が必要 Darwin and iOS macOS 10.13 High Sierra / 10.14 Mojave で動くのはGo 1.20 が最後 Go 1.21 からはmacOS 10.15 Catalina 以上が必要
  6. Go command amd64.v2 などのアーキテクチャフィーチャービルドタグが追加 各アーキテクチャに対して、より細かいレベルでファイルをビルド に含めるかどうか選択可能になった go help buildconstraint の内容

    ( 抜粋) The defined architecture feature build tags are: - For GOARCH=386, GO386=387 and GO386=sse2 set the 386.387 and 386.sse2 build tags, respectively. - For GOARCH=amd64, GOAMD64=v1, v2, and v3 correspond to the amd64.v1, amd64.v2, and amd64.v3 feature build tags. - For GOARCH=arm, GOARM=5, 6, and 7 correspond to the arm.5, arm.6, and arm.7 feature build tags. ...
  7. Go command go generate への -skip <pattern> の追加 <pattern> にマッチする

    //go:generate ディレクティブをスキップ する go test への -skip <pattern> の追加 <pattern> にマッチするテスト、サブテスト、サンプルをスキップ する
  8. Go command go build 、go install 等のビルド関連コマンドに -pgo flag が追加

    フラグを付与すると、profile-guided optimization が有効化される アプリケーションの振る舞いに対してプロファイリングを行い、 その情報をコンパイラ最適化に使用する 詳細はこの後のCIARANA さんの発表をご覧ください https://go.dev/blog/pgo-preview
  9. Go command (Cover) go build 、go install 等のビルド関連コマンドに -cover flag

    が追加 プログラムのコードカバレッジプロファイルを取得し、ファイルと して出力する 統合テストで使われることを意図している カバレッジ情報の収集は、ビルドされたバイナリの実行時に行わ れ、 GOCOVERDIR 環境変数で指定されたディレクトリに出力される 詳細はこの後のhiro さんの発表をご覧ください https://go.dev/testing/coverage/
  10. Cgo C ツールチェーンのないシステム上で、デフォルトでcgo が無効になっ た CGO_ENABLED と CC 環境変数が設定されておらず、デフォルト のC

    コンパイラ (clang / gcc) がpath に見つからなければ CGO_ENABLED=0 となる 明示的な上書きは可能 cgo の使えない環境で、自動的にcgo の利用が選択されてしまい、 ビルドに失敗するようなケースを防ぐのが目的
  11. Vet

  12. ネストされた関数でのループ変数キャプチャの検知改良 func TestToLower(t *testing.T) { tests := []struct { input

    string want string }{ {input: "A", want: "a"}, {input: "B", want: "b"}, } for _, tc := range tests { // tc := tc が抜けている t.Run(tc.input, func(t *testing.T) { t.Parallel() got := strings.ToLower(tc.input) if tc.want != got { t.Errorf("want: %s, got: %s", tc.want, got) } }) } }
  13. ネストされた関数でのループ変数キャプチャの検知改良 vet の出力結果 $ go vet ./... ./func_test.go:27:27: loop variable

    tc captured by func literal ./func_test.go:28:7: loop variable tc captured by func literal ./func_test.go:29:35: loop variable tc captured by func literal
  14. Compiler Go 1.18 と1.19 でジェネリクス関連の対応がありビルド速度が低下し たが、Go 1.20 ではビルド速度が最大10% 向上し、Go 1.17

    と同じレ ベルに戻った Go 1.19 と比較すると、生成されるコードのパフォーマンスも少し向 上している
  15. Linker Linux リンク時に動的インタプリタとしてglibc またはmusl を選択するように なった Windows Go linker がLLVM

    ベースの現代的なC ツールチェーンをサポートした その他 コンパイラが生成するシンボルの接頭辞が go: と type: となる
  16. Bootstrap Go 1.20 は、ブートストラップにGo 1.17.13 を必要とするようになっ た 1.18 / 1.19

    は、まずGo 1.17 を探し、見付からなければ1.4 にフォー ルバックしていた 1.20 は、まずGo 1.17.13 を探し、その後1.4 にフォールバックする
  17. crypto/ecdh package の追加 楕円曲線ディフィー・ヘルマン鍵共有 (ECDH) をサポートするための package が追加 ECDH は、ディフィー・ヘルマン鍵共有を、楕円曲線を使うように

    変更したもの crypto/elliptic package をECDH の実装に使っているプログラムは、今 後は代わりにcrypto/ecdh を使うべき
  18. 複数エラーのラップ fmt.Errorf が、複数の %w を受け付けるように errors.Join 関数が追加 errors.Is / As

    は、ラップされた複数のエラーに対して検査を行うよう 変更された 詳しくは、この後のtenntenn さんの発表をご覧ください
  19. HTTP ResponseController の追加 http.ResponseWriter をより簡単に操作出来るようにするために、 http.ResponseController が追加された これまでResponseWriter に対して(Flusher などに)

    型アサーションし つつ呼んでいた機能や設定を普通のメソッド呼び出しで行える ResponseController 経由で行える操作は、Flush 、Hijack 、 SetReadDeadline 、SetWriteDeadline の4 つ // SetWriteDeadline の例 (https://go.dev/doc/go1.20 より引用) func RequestHandler(w ResponseWriter, r *Request) { rc := http.NewResponseController(w) rc.SetWriteDeadline(time.Time{}) // disable Server.WriteTimeout when sending a large response io.Copy(w, bigData) }
  20. httputil.ReverseProxy へのRewrite hook の追 加 httputil.ReverseProxy に、Rewrite hook が追加された もともと存在していたDirector

    hook には、hook 内で追加したHTTP Header が意図せず削除される(追加出来ない)場合があると言う 問題があった Rewrite hook によって、Director hook を置き換える フューチャー技術ブログの棚井さんの記事に詳細な解説があります https://future-architect.github.io/articles/20230131a/
  21. strings / bytes package CutPrefix / CutSuffix 関数の追加 TrimPrefix /

    TrimSuffix と同様の機能に加え、トリムが発生したかど うかを報告する Clone 関数の追加 (bytes のみ) byte slice のコピーを作成する package strings func CutPrefix(s, prefix string) (after string, found bool) func CutSuffix(s, suffix string) (before string, found bool) package bytes func CutPrefix(s, prefix []byte) (after []byte, found bool) func CutSuffix(s, suffix []byte) (before []byte, found bool) func Clone(b []byte) []byte
  22. context package WithCancelCause 関数、Cause 関数の追加 WithCancelCause は、WithCancel と異なり、エラーを引数に受け 取るキャンセル関数を返す context

    をキャンセルした理由を、このキャンセル関数に渡すこ とが出来る Cause 関数を使うことで、キャンセルされた理由のerror を取り出す ことが出来る context 自身のErr() メソッドは、引き続きcontext.Canceled エラー を返す
  23. time package DateTime, DateOnly, TimeOnly の3 つの最もよく使われる時間のフォ ーマット定数が追加された 時間同士を比較するTime.Compare メソッドが追加された

    const ( DateTime = "2006-01-02 15:04:05" DateOnly = "2006-01-02" TimeOnly = "15:04:05" ) // t がu より前なら-1 、t がu より後なら+1 、同じなら0 が返る func (t Time) Compare(u Time) int
  24. reflect package Value.Comparable メソッドの追加 v.Interface() == x がどんなx に対してもpanic しないかを返す

    Value.Equal メソッドの追加 値が等しいかどうかを返す。比較される型がcomparable でない場 合はpanic する Value.Grow() slice のcapacity を増加させる Value.SetZero() Value の保持する型のゼロ値を設定する