前書き
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つの新しい関数SliceData
、String
、StringData
が追加されたことです。
これらの関数は、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 build
、go 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を使用するパッケージは、net
、os/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()
呼び出しの後にループ変数への参照がある場合を報告するようになりました。
このような参照は、異なるイテレーションの変数の値を観測したり(通常はテストケースのスキップを引き起こします)、非同期で同期されていないアクセスによる無効な状態を引き起こしたりする可能性があります。
また、ツールはこれらの参照ミスを検出する箇所を拡張しました。
以前はループ本体の最後のステートメントのみを考慮していましたが、現在はif
、switch
、select
ステートメント内の最後のステートメントも再帰的に検査します。
時間フォーマットの誤りに対する新しい診断
vet
ツールは、Time.Format
およびtime.Parse
で使用される2006-02-01
(yyyy-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/pprof
やnet/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つのコントロールも追加されており、リクエストごとに読み取りおよび書き込みの期限を設定できます。
使用例
|
|
新しい 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-For
、X-Forwarded-Host
、およびX-Forwarded-Proto
ヘッダーを設定します。
Rewrite
フックを使用する場合、これらのヘッダーはデフォルトでは追加されません。
Rewrite フックの使用例
以下は、Rewrite
フックを使用してリクエストを転送する例です。
|
|
その他の変更点
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
新しいCutPrefix
とCutSuffix
関数は、TrimPrefix
およびTrimSuffix
に似ていますが、文字列がトリムされたかどうかも報告します。
新しいClone
関数は、バイトスライスのコピーを割り当てます。
context
新しいWithCancelCause
関数は、指定されたエラーでコンテキストをキャンセルする方法を提供します。
このエラーは、新しいCause
関数を呼び出すことで取得できます。
crypto/ecdsa
サポートされている曲線を使用する場合、すべての操作が定数時間で実行されるようになりました。
これにより、CPU時間が5%から30%増加しました(特にP-384およびP-521に影響します)。
新しいPrivateKey.ECDH
メソッドが追加され、ecdsa.PrivateKey
をecdh.PrivateKey
に変換できます。
crypto/ed25519
PrivateKey.Sign
メソッドおよびVerifyWithOptions
関数は、Ed25519phを使用してハッシュ済みメッセージの署名をサポートするようになりました。
これは、Options.HashFunc
がcrypto.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
をラップし、Seek
、Write
、およびWriteAt
メソッドを提供します。
これらのメソッドは、固定量だけ調整された有効なファイルオフセット位置で操作を実行します。
io/fs
新しいエラーSkipAll
が追加され、WalkDir
を即座に正常終了させます。
math/big
math/big
パッケージは広い用途と入力依存のタイミング特性により、暗号化の実装には不向きです。
標準ライブラリ内の暗号化パッケージは、攻撃者が制御する入力に対して複雑なInt
メソッドを呼び出さないようになりました。
将来的には、math/big
におけるバグがセキュリティ上の脆弱性と見なされるかどうかは、標準ライブラリへの影響範囲に依存します。
math/rand
math/rand
パッケージは、グローバルな乱数ジェネレータ(Float64
やInt
のようなトップレベル関数で使用されるもの)をランダムな値で自動的にシードするようになりました。
また、トップレベルの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
フックに似たコールバック関数を含み、ダイヤルコンテキストをパラメーターとして受け取ります。
ControlContext
がnil
でない場合、Control
は無視されます。
GoのDNSリゾルバは、trust-ad
リゾルバオプションを認識するようになりました。
resolv.conf
にoptions 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.IPv6loopback
とnet.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
メソッドSwap
、CompareAndSwap
、およびCompareAndDelete
により、既存のマップエントリをアトミックに更新できるようになりました。
syscall
FreeBSDでは、FreeBSD 11以前に必要だった互換性シムが削除されました。
Linuxでは、SysProcAttr.Cloneflags
フィールドで使用する追加のCLONE_*
定数が定義されました。
Linuxでは、新しいSysProcAttr.CgroupFD
およびSysProcAttr.UseCgroupFD
フィールドにより、特定のcgroupに子プロセスを配置する方法が提供されます。
testing
新しいメソッドB.Elapsed
が追加され、ベンチマークの現在の経過時間を報告します。
これにより、ReportMetric
とともにレートを計算するのに役立ちます。
T.Cleanup
に渡された関数内でT.Run
を呼び出すことは明確に定義されていませんでしたが、現在ではパニックを引き起こします。
time
新しいレイアウト定数DateTime
、DateOnly
、およびTimeOnly
が追加されました。
これらは、公開されているGoソースコードの調査でよく使用されるレイアウト文字列3種類に名前を付けたものです。
新しいTime.Compare
メソッドにより、2つの時間を比較できます。
Parse
は、入力内のナノ秒未満の精度を無視するようになり、これらの桁をエラーとして報告しなくなりました。
Time.MarshalJSON
メソッドは、RFC 3339への準拠に関してより厳格になりました。
unicode/utf16
新しいAppendRune
関数が追加され、指定されたルーンのUTF-16エンコーディングをuint16
スライスに追加できます。これはutf8.AppendRune
に類似しています。