Go1.20のリリースノート(日本語訳)

JavaScriptを有効にしてください

前書き

Go1.20のリリースノートをChatGPTで日本語に翻訳しました。
Go 1.20 Release Notes

Go 1.20の紹介

最新のGoリリースであるバージョン1.20は、前回のGo 1.19のリリースから6か月後に公開されました。
このリリースの変更点の多くは、ツールチェーン、ランタイム、ライブラリの実装に関するものです。
これまでと同様に、Go 1の互換性ポリシーが維持されており、ほとんどのGoプログラムはこれまで通りコンパイルおよび実行できると予想されます。

言語の変更

Go 1.20では、言語に4つの変更が加えられています。

1つ目の変更は、スライスから配列ポインタへの変換に関するものです。
Go 1.17で導入されたこの機能が拡張され、スライスから配列への変換が可能になりました。
たとえば、スライスxに対して、[4]byte(x)と記述できるようになり、これまで必要だった*(*[4]byte)(x)という記述が不要になりました。

2つ目の変更は、unsafeパッケージに3つの新しい関数SliceDataStringStringDataが追加されたことです。
これらの関数は、Go 1.17で導入されたSlice関数と合わせて、スライスと文字列の値をその正確な表現に依存せずに構築および分解する完全な能力を提供します。

3つ目の変更は、構造体と配列の比較に関する仕様の明確化です。
構造体の値は、フィールドが構造体型定義で定義された順序に従って1フィールドずつ比較され、最初の不一致で比較が終了します。
同様に、配列の値はインデックスが増加する順序で1要素ずつ比較されます。これらの変更により、一部の比較がパニックを引き起こすかどうかが仕様上明確になりました。
ただし、既存のプログラムには影響がありません。新しい仕様の記述は、これまで実装が常に行ってきたことを明文化したものです。

4つ目の変更は、comparable制約を満たす型についてです。
型引数が厳密に比較可能でなくても(ランタイムでの比較がパニックを引き起こす可能性があっても)、comparable制約を満たすようになりました。
これにより、ユーザー定義のジェネリックマップキーにcomparable制約を持つ型パラメータを、インターフェース型やインターフェース型を含む複合型などの厳密に比較可能でない型引数でインスタンス化することが可能になりました。

サポート環境

Windows

Go 1.20は、Windows 7、Windows 8、Server 2008、およびServer 2012のいずれかのリリースで動作する最後のバージョンです。
Go 1.21では、少なくともWindows 10またはServer 2016が必要になります。

macOSとiOS

Go 1.20は、macOS 10.13 High Sierraおよび10.14 Mojaveで動作する最後のバージョンです。
Go 1.21では、macOS 10.15 Catalina以降が必要になります。

FreeBSD/RISC-V

Go 1.20は、RISC-V上のFreeBSD(GOOS=freebsd, GOARCH=riscv64)に対する実験的なサポートを追加しました。

ツール

Goコマンド

$GOROOT/pkgディレクトリは、標準ライブラリの事前コンパイル済みパッケージアーカイブを格納しなくなりました。
これにより、go installはそれらを書き込まず、go buildはそれらを確認せず、Goの配布物にも含まれません。
代わりに、標準ライブラリ内のパッケージは、必要に応じてビルドされ、ビルドキャッシュにキャッシュされます。
この挙動は、GOROOT外のパッケージと同様です。この変更により、Go配布物のサイズが削減され、cgoを使用するパッケージにおけるCツールチェーンのズレを回避できます。

go test -jsonの実装が改良され、より堅牢になりました。go test -jsonを実行するプログラムは更新の必要はありませんが、go tool test2jsonを直接呼び出すプログラムは、テストバイナリを-v=test2jsonで実行する必要があります(例: go test -v=test2json./pkg.test -test.v=test2json)。
単なる-vでは動作しません。

go test -jsonに関連する変更として、各テストプログラムの実行開始時にActionがstartに設定されたイベントが追加されました。
複数のテストをgoコマンドで実行する場合、これらの開始イベントはコマンドラインで指定されたパッケージと同じ順序で必ず発行されます。

goコマンドは、新たにアーキテクチャ機能ビルドタグ(例: amd64.v2)を定義しました。
これにより、特定のアーキテクチャ機能の有無に基づいてパッケージ実装ファイルを選択できるようになります。
詳細はgo help buildconstraint を参照してください。

goのサブコマンドは、-C <dir>オプションを受け付けるようになり、コマンド実行前に作業ディレクトリを<dir>に変更できます。
この機能は、複数の異なるモジュールでコマンドを実行するスクリプトに便利です。

go buildおよびgo testコマンドは、Go 1.16以降非推奨だった-iフラグをサポートしなくなりました。

go generateコマンドは、-skip <pattern>を受け付けるようになり、//go:generateディレクティブの中で<pattern>に一致するものをスキップできます。

go testコマンドは、-skip <pattern>を受け付けるようになり、テスト、サブテスト、または例の中で<pattern>に一致するものをスキップできます。

メインモジュールがGOPATH/src内にある場合、go installは非メインパッケージ用のライブラリをGOPATH/pkgにインストールしなくなり、go listはそのようなパッケージに対してTargetフィールドを報告しなくなりました。(モジュールモードでは、コンパイル済みパッケージはビルドキャッシュのみに格納されますが、以前はGOPATHインストールターゲットが予期せず適用されていました。)

go buildgo install、および他のビルド関連コマンドは、プロファイルガイド最適化(PGO)を有効にする-pgoフラグをサポートするようになりました。
このフラグは、プロファイルのファイルパスを指定します。
-pgo=autoを指定すると、メインパッケージのディレクトリ内のdefault.pgoという名前のファイルを探し、存在する場合にそれを使用します。
このモードは現在、コマンドラインで単一のメインパッケージを指定する必要がありますが、将来的にはこの制約を解除する予定です。
-pgo=offを指定すると、プロファイルガイド最適化を無効にします。

また、ビルド関連のコマンドは-coverフラグをサポートするようになり、指定されたターゲットをコードカバレッジ計測付きでビルドできます。
この詳細については「Cover 」セクションを参照してください。

go version

go version -mコマンドは、より多くの種類のGoバイナリを読み取れるようになりました。
特に、go build -buildmode=c-sharedでビルドされたWindows DLLや、実行権限のないLinuxバイナリをサポートしています。

Cgo

goコマンドは、Cツールチェーンがないシステムでデフォルトでcgoを無効化するようになりました。
具体的には、CGO_ENABLED環境変数が設定されていない場合、CC環境変数が設定されておらず、パス内にデフォルトのCコンパイラ(通常はclangやgcc)が見つからない場合、CGO_ENABLEDはデフォルトで0に設定されます。このデフォルトの挙動は、CGO_ENABLEDを明示的に設定することで上書きできます。

このデフォルトの変更の最も重要な影響は、CコンパイラがインストールされていないシステムにGoをインストールした場合に発生します。
その場合、標準ライブラリでcgoを使用するパッケージが、事前配布されていたパッケージアーカイブ(上記の通り削除済み)や、cgoの使用を試みて失敗する代わりに、純粋なGoでビルドされるようになります。これにより、最小限のコンテナ環境やmacOSなどでGoの動作が改善されます。
macOSでは、Go 1.16以降、cgoベースのパッケージに事前配布されたアーカイブは使用されていません。

標準ライブラリでcgoを使用するパッケージは、netos/user、およびpluginです。
macOSでは、netおよびos/userパッケージがcgoを使用しないように書き換えられました。
これにより、cgoビルド、非cgoビルド、クロスコンパイルビルドで同じコードが使用されます。
Windowsでは、これらのパッケージは元々cgoを使用していません。
他のシステムでは、cgoを無効にしてビルドすると、これらのパッケージの純粋なGo版が使用されます。

この変更に伴い、macOSでnetパッケージを使用するGoコードを-buildmode=c-archiveでビルドした場合、生成されたアーカイブをCプログラムにリンクする際に、Cコードのリンク時に-lresolvを渡す必要があります。

また、macOSでは、競合状態検出器(race detector)がcgoを使用しないように書き換えられました。
そのため、競合状態検出が有効なプログラムをXcodeなしでビルドおよび実行できるようになりました。
ただし、Linuxや他のUnixシステム、Windowsでは、競合状態検出器を使用するためにホストCツールチェーンが必要です。

Cover

Go 1.20では、ユニットテストだけでなく、プログラム全体(アプリケーションや統合テスト)のコードカバレッジプロファイルを収集することがサポートされました。

プログラムのカバレッジデータを収集するには、go build-coverフラグを使用してビルドし、生成されたバイナリをGOCOVERDIR環境変数でカバレッジプロファイルの出力ディレクトリを指定して実行します。
詳細については「統合テスト用カバレッジ 」のページをご覧ください。設計と実装の詳細については提案書 を参照してください。

Vet

ネストした関数によるループ変数キャプチャの検出の改善

vetツールは、サブテスト関数内でT.Parallel()呼び出しの後にループ変数への参照がある場合を報告するようになりました。
このような参照は、異なるイテレーションの変数の値を観測したり(通常はテストケースのスキップを引き起こします)、非同期で同期されていないアクセスによる無効な状態を引き起こしたりする可能性があります。

また、ツールはこれらの参照ミスを検出する箇所を拡張しました。
以前はループ本体の最後のステートメントのみを考慮していましたが、現在はifswitchselectステートメント内の最後のステートメントも再帰的に検査します。

時間フォーマットの誤りに対する新しい診断

vetツールは、Time.Formatおよびtime.Parseで使用される2006-02-01yyyy-dd-mm)という時間フォーマットの使用を報告するようになりました。
この形式は一般的な日付標準には存在せず、ISO 8601の日付フォーマット(yyyy-mm-dd)を使用しようとして間違えて使用されることがよくあります。

Runtime

ガベージコレクタの内部データ構造が再編成され、メモリ使用量とCPU効率の両方が改善されました。
この変更により、メモリのオーバーヘッドが削減され、全体的なCPUパフォーマンスが最大2%向上します。

一部の状況で、ガベージコレクタのゴルーチンアシストの動作が不安定になる問題が軽減されました。

Go 1.20では、新しいruntime/coverageパッケージが追加されました。
このパッケージには、サーバープログラムや長時間実行されるプログラムのようにos.Exit()で終了しないプログラムから実行時にカバレッジプロファイルデータを書き込むためのAPIが含まれています。

コンパイラ

Go 1.20では、プロファイルガイド最適化(PGO)のプレビューサポートが追加されました。
PGOを使用すると、実行時プロファイル情報に基づいて、アプリケーションやワークロードに特化した最適化をツールチェーンが行うことができます。
現在、コンパイラはpprofのCPUプロファイルをサポートしており、これはruntime/pprofnet/http/pprofパッケージなどの通常の手段を通じて収集できます。
PGOを有効にするには、go build-pgoフラグを使用し、pprofプロファイルファイルのパスを指定します(goコマンドを参照 )。
Go 1.20では、PGOを利用して頻繁に呼び出される箇所(ホットコールサイト)で関数のインライン化をより積極的に行います。
代表的なGoプログラムセットのベンチマークでは、プロファイルガイドによるインライン化最適化を有効にすると、パフォーマンスが約3–4%向上することが示されています。
詳細なドキュメントはPGOユーザーガイド を参照してください。
将来的には、さらに多くのプロファイルガイド最適化を追加する予定です。なお、PGOはプレビュー段階であるため、適切な注意を払って使用してください。

Go 1.20のコンパイラは、コンパイラ内部データを処理する新しい方法にフロントエンドをアップグレードしました。
これにより、いくつかのジェネリック型の問題が修正され、ジェネリック関数やメソッド内での型宣言が可能になりました。

コンパイラは、匿名インターフェースサイクルをデフォルトでコンパイラエラーとして拒否するようになりました。
これらは埋め込みインターフェースの複雑な使用法から生じ、これまでも微妙な正確性の問題がありましたが、実際に使用されている証拠はありません。
この変更で影響を受けるユーザーからの報告がない場合、Go 1.22で言語仕様を正式に更新し、ツール開発者がこれらをサポートする必要がなくなるようにする予定です。

Go 1.18および1.19では、主にジェネリック対応の追加やそれに伴う作業によってビルド速度が低下していました。
Go 1.20では、ビルド速度が最大10%改善され、Go 1.17と同等のレベルに戻りました。Go 1.19と比較すると、生成されるコードのパフォーマンスも一般的にわずかに向上しています。

リンカ

Linuxでは、リンカがリンク時にglibcまたはmuslのダイナミックインタープリタを選択するようになりました。

Windowsでは、Goリンカが最新のLLVMベースのCツールチェーンをサポートするようになりました。

Go 1.20では、コンパイラ生成のシンボルにgo:およびtype:という接頭辞を使用するようになりました(従来はgo.およびtype..)。
これにより、名前がgo.で始まるユーザーパッケージとの混乱を回避できます。
debug/gosymパッケージは、Go 1.20以降でビルドされたバイナリのこの新しい命名規則を理解します。

ブートストラップ

ソースからGoリリースをビルドする際、GOROOT_BOOTSTRAPが設定されていない場合、以前のバージョンのGoはブートストラップツールチェーンとしてGo 1.4以降を$HOME/go1.4(Windowsでは%HOMEDRIVE%%HOMEPATH%\go1.4)ディレクトリで探していました。
Go 1.18およびGo 1.19では、Go 1.17を必要とするGo 1.20のブートストラップを見越して、まず$HOME/go1.17または$HOME/sdk/go1.17を確認し、その後に$HOME/go1.4を確認する仕様になっていました。

Go 1.20では、ブートストラップにGo 1.17リリースが必要ですが、最新のポイントリリース(最終リリース)を採用すべきであると判断したため、Go 1.17.13が必要になります。
Go 1.20は、まず$HOME/go1.17.13または$HOME/sdk/go1.17.13を探し、その後$HOME/go1.4を確認します(特定のシステムで$HOME/go1.4のパスがハードコードされており、新しいGoツールチェーンがそこにインストールされている場合をサポートするため)。

将来的には、ブートストラップツールチェーンのバージョンを年に1回程度進める予定です。
特に、Go 1.22ではGo 1.20の最終ポイントリリースがブートストラップに必要になると予想されています。

標準ライブラリ

新しい crypto/ecdh パッケージ

Go 1.20では、新しいcrypto/ecdhパッケージが追加され、NISTカーブおよびCurve25519を用いた楕円曲線ディフィー・ヘルマン(ECDH)鍵交換を明示的にサポートします。

プログラムでは、ECDHのためにcrypto/ecdhを使用することが推奨されます。
より高度なユースケースでは、crypto/ellipticの低レベル機能やサードパーティのモジュールを使用することが適しています。

複数エラーのラッピング

Go 1.20では、エラーラッピングのサポートが拡張され、1つのエラーが複数のエラーをラップできるようになりました。

エラーe[]errorを返すUnwrapメソッドを提供することで、複数のエラーをラップできます。

errors.Isおよびerrors.As関数が更新され、複数のエラーをラップした場合でも適切に検査できるようになりました。

fmt.Errorf関数では、%w形式指定子を複数回使用できるようになり、これによってすべてのエラーオペランドをラップするエラーを返します。

新しい関数errors.Joinが追加され、エラーのリストをラップするエラーを返します。

HTTP ResponseController

新しい"net/http".ResponseController型が追加され、"net/http".ResponseWriterインターフェースでは扱えないリクエストごとの拡張機能にアクセスできるようになりました。

これまで、リクエストごとの機能を追加するために、FlusherのようなResponseWriterが実装できるオプションのインターフェースを定義していました。
しかし、これらのインターフェースは発見が難しく、使いにくいものでした。

ResponseController型は、各ハンドラーに対するコントロールをより明確かつ発見しやすい方法で提供します。
Go 1.20では、SetReadDeadlineおよびSetWriteDeadlineという2つのコントロールも追加されており、リクエストごとに読み取りおよび書き込みの期限を設定できます。

使用例

1
2
3
4
5
func RequestHandler(w ResponseWriter, r *Request) {
  rc := http.NewResponseController(w)
  rc.SetWriteDeadline(time.Time{}) // 大量のレスポンスを送信する際にServer.WriteTimeoutを無効化
  io.Copy(w, bigData)
}

新しい ReverseProxy Rewrite フック

httputil.ReverseProxyのフォワーディングプロキシに新しいRewriteフック関数が追加され、以前のDirectorフックを置き換える形となりました。

Rewrite フックの特徴

Rewriteフックは、プロキシが受信したリクエストと送信するリクエストの両方を含むProxyRequestパラメータを受け取ります。
これにより、Directorフックのように送信リクエストだけを操作するのではなく、受信リクエストを考慮した処理が可能になります。
この設計により、フックによって追加されたヘッダーが、悪意のある受信リクエストによって転送前に削除されるといったシナリオを回避できます(詳細はissue #50580 を参照)。

ProxyRequest.SetURL メソッド

ProxyRequest.SetURLメソッドは、送信リクエストを指定された宛先にルーティングします。このメソッドは、以前のNewSingleHostReverseProxy関数を置き換えます。
NewSingleHostReverseProxyとは異なり、SetURLは送信リクエストのHostヘッダーも設定します。

ProxyRequest.SetXForwarded メソッド

ProxyRequest.SetXForwardedメソッドは、送信リクエストのX-Forwarded-ForX-Forwarded-Host、およびX-Forwarded-Protoヘッダーを設定します。
Rewriteフックを使用する場合、これらのヘッダーはデフォルトでは追加されません。

Rewrite フックの使用例

以下は、Rewriteフックを使用してリクエストを転送する例です。

1
2
3
4
5
6
7
proxyHandler := &httputil.ReverseProxy{
  Rewrite: func(r *httputil.ProxyRequest) {
    r.SetURL(outboundURL) // リクエストを outboundURL に転送
    r.SetXForwarded()     // X-Forwarded-* ヘッダーを設定
    r.Out.Header.Set("X-Additional-Header", "プロキシによって設定されたヘッダー")
  },
}

その他の変更点

ReverseProxyは、受信リクエストにUser-Agentヘッダーがない場合、転送リクエストにUser-Agentヘッダーを追加しなくなりました。

ライブラリの細かい変更

Go 1の互換性ポリシーを考慮しながら、ライブラリに様々な小さな変更と更新が加えられました。
また、ここでは列挙していませんが、様々なパフォーマンス改善も行われています。

archive/tar

環境変数GODEBUG=tarinsecurepath=0が設定されている場合、Reader.Nextメソッドは以下の条件を満たすエントリに対してエラーErrInsecurePathを返すようになりました。

  • 絶対パスを含むファイル名
  • 現在のディレクトリ外を参照するファイル名
  • 無効な文字を含むファイル名
  • (Windowsの場合)NULのような予約済みの名前

将来のGoのバージョンでは、不安全なパスがデフォルトで無効になる可能性があります。

archive/zip

環境変数GODEBUG=zipinsecurepath=0が設定されている場合、NewReaderは以下の条件を満たすアーカイブを開こうとした際にエラーErrInsecurePathを返すようになりました。

  • 絶対パスを含むファイル名
  • 現在のディレクトリ外を参照するファイル名
  • 無効な文字を含むファイル名
  • (Windowsの場合)NULのような予約済みの名前

将来のGoのバージョンでは、不安全なパスがデフォルトで無効になる可能性があります。

ディレクトリファイルにファイルデータが含まれている場合、読み込み時にエラーが返されるようになりました。
これは、zip仕様ではディレクトリファイルがファイルデータを含むことを許可していないためであり、不正なアーカイブを読み取る場合のみ影響します。

bytes

新しいCutPrefixCutSuffix関数は、TrimPrefixおよびTrimSuffixに似ていますが、文字列がトリムされたかどうかも報告します。
新しいClone関数は、バイトスライスのコピーを割り当てます。

context

新しいWithCancelCause関数は、指定されたエラーでコンテキストをキャンセルする方法を提供します。
このエラーは、新しいCause関数を呼び出すことで取得できます。

crypto/ecdsa

サポートされている曲線を使用する場合、すべての操作が定数時間で実行されるようになりました。
これにより、CPU時間が5%から30%増加しました(特にP-384およびP-521に影響します)。
新しいPrivateKey.ECDHメソッドが追加され、ecdsa.PrivateKeyecdh.PrivateKeyに変換できます。

crypto/ed25519

PrivateKey.SignメソッドおよびVerifyWithOptions関数は、Ed25519phを使用してハッシュ済みメッセージの署名をサポートするようになりました。
これは、Options.HashFunccrypto.SHA512を返すことで示されます。
また、新しいOptions.Contextフィールドを設定することで、コンテキスト付きのEd25519ctxおよびEd25519phもサポートします。

crypto/rsa

新しいフィールドOAEPOptions.MGFHashにより、OAEP復号化のためのMGF1ハッシュを個別に設定できるようになりました。
crypto/rsaは新しい安全な定数時間のバックエンドを使用するようになりました。
この変更により、復号化操作のCPU実行時間が約15%(amd64上のRSA-2048)から45%(arm64上のRSA-4096)増加しました。
32ビットアーキテクチャではさらに増加します。暗号化操作は以前より約20倍遅くなりましたが、それでも復号化より5-10倍高速です。
将来のリリースで性能の改善が期待されています。
PrecomputedValuesのフィールドを変更したり手動で生成したりしてはいけません。

crypto/subtle

新しい関数XORBytesが追加され、2つのバイトスライスをXOR演算で組み合わせることができます。

crypto/tls

パースされた証明書は、その証明書を使用しているすべてのクライアントで共有されるようになりました。
サーバーやサーバーのコレクションに多くの同時接続を行うプログラムでは、メモリ節約の効果が大きい場合があります。
証明書の検証エラーが原因でハンドシェイクが失敗した場合、TLSクライアントおよびサーバーは、新しい型CertificateVerificationErrorのエラーを返すようになりました。
このエラーには提示された証明書が含まれます。

crypto/x509

ParsePKCS8PrivateKeyおよびMarshalPKCS8PrivateKeyは、新たに*crypto/ecdh.PrivateKey型のキーをサポートするようになりました。
同様に、ParsePKIXPublicKeyおよびMarshalPKIXPublicKeyは、*crypto/ecdh.PublicKey型のキーをサポートします。
NISTカーブのキーをパースすると、引き続き*ecdsa.PublicKeyおよび*ecdsa.PrivateKey型の値が返されます。
それらをcrypto/ecdh型に変換するには、新しいECDHメソッドを使用してください。

新しいSetFallbackRoots関数により、ランタイムでオペレーティングシステムの検証者または標準プラットフォームのルートバンドルが利用できない場合に使用されるフォールバックルート証明書のセットをプログラム内で定義できます。
この機能は、golang.org/x/crypto/x509roots/fallbackという新しいパッケージと共に使用されるのが一般的です。このパッケージは最新のルートバンドルを提供します。

debug/elf

Section.DataまたはSection.Openから返されるリーダーを使用してSHT_NOBITSセクションから読み取ろうとすると、エラーが返されるようになりました。
LoongArchシステムで使用するための追加のR_LARCH_*定数が定義されました。
PPC64 ELFv2再配置で使用するための追加のR_PPC64_*定数が定義されました。
R_PPC64_SECTOFF_LO_DSの定数値が修正され、61から62に変更されました。

debug/gosym

Goのシンボル命名規則の変更に伴い、Goバイナリを処理するツールは、古いバイナリと新しいバイナリの両方を透過的に処理できるように、Go 1.20のdebug/gosymパッケージを使用する必要があります。

debug/pe

RISC-Vシステムで使用するための追加のIMAGE_FILE_MACHINE_RISCV*定数が定義されました。

encoding/binary

ReadVarintおよびReadUvarint関数は、部分的な値を読み取った後にio.ErrUnexpectedEOFを返すようになりました(以前はio.EOFを返していました)。

encoding/xml

新しいEncoder.Closeメソッドが追加され、エンコードを終了する際に未クローズの要素をチェックすることができます。
デコーダーは以下を拒否するようになりました:
2つ以上のコロンを含む要素や属性名(例: <a:b:c>)。
空文字列に解決される名前空間(例: xmlns:a="")。
デコーダーは、開くタグと閉じるタグで異なる名前空間プレフィックスを使用する要素を拒否するようになりました(これらのプレフィックスが同じ名前空間を示す場合でも)。

errors

新しいJoin関数が追加され、エラーのリストをラップするエラーを返します。

fmt

Errorf関数は%w形式指定子を複数回使用できるようになり、%wのすべての引数のリストをアンラップするエラーを返します。
新しいFormatString関数が追加され、Stateに対応するフォーマット指定子を復元します。これはFormatterの実装で役立ちます。

go/ast

新しいRangeStmt.Rangeフィールドが追加され、rangeステートメント内のrangeキーワードの位置を記録します。
新しいFile.FileStartおよびFile.FileEndフィールドが追加され、ソースファイル全体の開始位置と終了位置を記録します。

go/token

新しいFileSet.RemoveFileメソッドが追加され、FileSetからファイルを削除できます。
長時間実行されるプログラムは、不要になったファイルに関連付けられたメモリを解放するためにこれを使用できます。

go/types

新しいSatisfies関数が追加され、型が制約を満たしているかどうかを報告します。
この変更により、制約を満たすこととインターフェースを実装することを区別する新しい言語セマンティクスに対応しています。

html/template

Go 1.20.3以降では、ECMAScript 6のテンプレートリテラル内でのアクションが禁止されました。
この動作は、環境変数GODEBUG=jstmpllitinterp=1を設定することで元に戻すことができます。

io

新しいOffsetWriterは、WriterAtをラップし、SeekWrite、およびWriteAtメソッドを提供します。
これらのメソッドは、固定量だけ調整された有効なファイルオフセット位置で操作を実行します。

io/fs

新しいエラーSkipAllが追加され、WalkDirを即座に正常終了させます。

math/big

math/bigパッケージは広い用途と入力依存のタイミング特性により、暗号化の実装には不向きです。
標準ライブラリ内の暗号化パッケージは、攻撃者が制御する入力に対して複雑なIntメソッドを呼び出さないようになりました。

将来的には、math/bigにおけるバグがセキュリティ上の脆弱性と見なされるかどうかは、標準ライブラリへの影響範囲に依存します。

math/rand

math/randパッケージは、グローバルな乱数ジェネレータ(Float64Intのようなトップレベル関数で使用されるもの)をランダムな値で自動的にシードするようになりました。
また、トップレベルのSeed関数は非推奨となりました。

再現可能な乱数列を必要とするプログラムでは、rand.New(rand.NewSource(seed))を使用して独自の乱数ソースを作成することを推奨します。

以前の一貫したグローバルシード動作が必要なプログラムでは、環境変数GODEBUG=randautoseed=0を設定することで動作を変更できます。

トップレベルのRead関数も非推奨となりました。ほとんどの場合、crypto/rand.Readの方が適切です。

mime

ParseMediaType関数は、パラメータ名が重複していても、その値が同じである限り許可するようになりました。

mime/multipart

Reader型のメソッドは、内部のio.Readerから返されるエラーをラップするようになりました。
Go 1.19.8以降、このパッケージでは、悪意のある入力を防ぐために処理するMIMEデータのサイズに制限が設けられています。
Reader.NextPartおよびReader.NextRawPartは、パート内のヘッダー数を最大10000に制限し、Reader.ReadFormはすべてのFileHeaders内のヘッダー数を最大10000に制限します。
これらの制限は環境変数GODEBUG=multipartmaxheadersで調整できます。
また、Reader.ReadFormはフォーム内のパート数を最大1000に制限します。この制限は環境変数GODEBUG=multipartmaxpartsで調整できます。

net

LookupCNAME関数は、CNAMEレコードが存在する場合にその内容を一貫して返すようになりました。
以前は、UnixシステムやGo独自のリゾルバを使用している場合に、CNAMEレコードがA、AAAA、またはCNAMEレコードに関連付けられていない名前を参照しているとエラーを返していました。
この変更により、LookupCNAMEはCNAMEが存在する限り成功するようになり、以前のWindowsの動作と一致するようになりました。

Interface.Flagsに新しいフラグFlagRunningが追加され、運用中のインターフェースを示します。
管理上設定されているがアクティブでないインターフェース(例: ネットワークケーブルが接続されていない場合)は、FlagUpが設定されますが、FlagRunningは設定されません。

新しいDialer.ControlContextフィールドは、既存のDialer.Controlフックに似たコールバック関数を含み、ダイヤルコンテキストをパラメーターとして受け取ります。
ControlContextnilでない場合、Controlは無視されます。

GoのDNSリゾルバは、trust-adリゾルバオプションを認識するようになりました。
resolv.confoptions trust-adが設定されている場合、GoリゾルバはDNSクエリでADビットを設定します。
ただし、リゾルバは応答内のADビットを使用しません。DNS解決は、/etc/nsswitch.confの変更を検出し、変更時にファイルを再読み込みするようになりました。
チェックは5秒ごとに1回行われ、/etc/hostsおよび/etc/resolv.confの以前の処理と一致します。

net/http

ResponseWriter.WriteHeader関数は、1xxステータスコードの送信をサポートするようになりました。
新しいServer.DisableGeneralOptionsHandler設定により、デフォルトのOPTIONS *ハンドラーを無効化できます。
新しいTransport.OnProxyConnectResponseフックは、プロキシへのCONNECTリクエストに対するHTTP応答を受け取ったときに呼び出されます。
HTTPサーバーは、ボディを含むHEADリクエストを受け入れるようになり、無効として拒否しなくなりました。

HTTP/2ストリームエラーは、errors.Asを使用してgolang.org/x/net/http2.StreamErrorに変換できるようになりました。
クッキー名の前後の空白が無効とされるのではなく、トリムされるようになりました。
例えば、"name =value"というクッキー設定は、クッキー"name"を設定するものとして受け入れられるようになりました。
空のExpiresフィールドを持つクッキーは、有効と見なされます。Cookie.Validは、Expiresが設定されている場合のみチェックします。

net/netip

新しいIPv6LinkLocalAllRoutersおよびIPv6Loopback関数は、それぞれnet.IPv6loopbacknet.IPv6linklocalallroutersに相当するnet/netipの機能です。

os

Windowsでは、MkdirおよびStatで名前NULが特別扱いされなくなりました。

Windowsでは、File.Statがディレクトリの属性を取得する際にファイルハンドルを使用するようになりました。
以前はOpenに渡されたパスを使用していましたが、ファイルが移動または置き換えられた場合、それがハンドルで表されるファイルではない可能性がありました。
この変更により、ディレクトリをOpenするときにFILE_SHARE_DELETEアクセスなしで開くようになり、通常のファイルの動作と一致するようになりました。

Windowsでは、File.Seekがディレクトリの先頭へのシークをサポートするようになりました。

os/exec

新しいCmdフィールドCancelおよびWaitDelayにより、関連付けられたコンテキストがキャンセルされた場合や、プロセスが終了しても子プロセスがI/Oパイプを保持している場合のCmdの動作を指定できます。

path/filepath

新しいエラーSkipAllにより、Walkを正常に終了しつつ即座に停止させることができます。

新しいIsLocal関数は、パスがディレクトリに対して字句的にローカルであるかどうかを報告します。
例えば、IsLocal(p)trueの場合、Open(p)は現在のディレクトリをルートとするサブツリー内のファイルを指します。

reflect

新しいValue.ComparableおよびValue.Equalメソッドにより、2つのValueを比較して等価性を判定できます。
Comparableは、指定されたValueレシーバーに対してEqualが有効な操作であるかどうかを報告します。

新しいValue.Growメソッドは、スライスを拡張してさらにn個の要素を確保します。

新しいValue.SetZeroメソッドは、値をその型のゼロ値に設定します。

Go 1.18で導入されたValue.SetIterKeyおよびValue.SetIterValueメソッドは、パフォーマンス向上のための最適化として設計されています。
v.SetIterKey(it)v.Set(it.Key())と等価であることを意図していましたが、実装では非公開フィールドの使用チェックが省略されていました。
Go 1.20では、これらのメソッドに非公開フィールドチェックが含まれるよう修正されました。

regexp

Go 1.19.2およびGo 1.18.7では、正規表現パーサーにセキュリティ修正が加えられ、メモリを過剰に消費する非常に大きな式を拒否するようになりました。
Goのパッチリリースでは新しいAPIを導入しないため、この場合はsyntax.ErrInternalErrorが返されていました。
Go 1.20では、より具体的なエラーであるsyntax.ErrLargeが追加され、このエラーが代わりに返されるようになりました。

runtime/cgo

Go 1.20では、新しいIncompleteマーカ型が追加されました。cgoによって生成されるコードは、不完全なC型をマークするためにcgo.Incompleteを使用します。

runtime/metrics

Go 1.20では、新しいメトリクスがサポートされるようになりました。
これには、現在のGOMAXPROCS設定(/sched/gomaxprocs:threads)、実行されたcgo呼び出しの総数(/cgo/go-to-c-calls:calls)、ミューテックスブロック時間の合計(/sync/mutex/wait/total:seconds)、およびガベージコレクションに費やされた時間のさまざまな測定値が含まれます。

時間ベースのヒストグラムメトリクスは精度が若干低下しましたが、必要とするメモリが大幅に削減されました。

runtime/pprof

ミューテックスプロファイルのサンプルが事前にスケーリングされるようになり、実行中にサンプリングレートが変更された場合でも、古いミューテックスプロファイルサンプルが正しくスケーリングされるようになりました。

Windowsで収集されたプロファイルには、位置依存バイナリに関するシンボリゼーションの問題を修正するメモリマッピング情報が含まれるようになりました。

runtime/trace

ガベージコレクタのバックグラウンドスイーパーが頻繁に休止しなくなり、実行トレースにおける余分なイベントが大幅に減少しました。

strings

新しいCutPrefixおよびCutSuffix関数が追加されました。
これらはTrimPrefixおよびTrimSuffixに似ていますが、文字列がトリムされたかどうかを報告する機能が追加されています。

sync

新しいMapメソッドSwapCompareAndSwap、およびCompareAndDeleteにより、既存のマップエントリをアトミックに更新できるようになりました。

syscall

FreeBSDでは、FreeBSD 11以前に必要だった互換性シムが削除されました。

Linuxでは、SysProcAttr.Cloneflagsフィールドで使用する追加のCLONE_*定数が定義されました。

Linuxでは、新しいSysProcAttr.CgroupFDおよびSysProcAttr.UseCgroupFDフィールドにより、特定のcgroupに子プロセスを配置する方法が提供されます。

testing

新しいメソッドB.Elapsedが追加され、ベンチマークの現在の経過時間を報告します。
これにより、ReportMetricとともにレートを計算するのに役立ちます。

T.Cleanupに渡された関数内でT.Runを呼び出すことは明確に定義されていませんでしたが、現在ではパニックを引き起こします。

time

新しいレイアウト定数DateTimeDateOnly、およびTimeOnlyが追加されました。
これらは、公開されているGoソースコードの調査でよく使用されるレイアウト文字列3種類に名前を付けたものです。

新しいTime.Compareメソッドにより、2つの時間を比較できます。

Parseは、入力内のナノ秒未満の精度を無視するようになり、これらの桁をエラーとして報告しなくなりました。

Time.MarshalJSONメソッドは、RFC 3339への準拠に関してより厳格になりました。

unicode/utf16

新しいAppendRune関数が追加され、指定されたルーンのUTF-16エンコーディングをuint16スライスに追加できます。これはutf8.AppendRuneに類似しています。


スポンサーリンク

共有

もふもふ
著者
もふもふ
プログラマ。汎用系→ゲームエンジニア→Webエンジニア→QAエンジニア