前書き
Go1.23のリリースノートをChatGPTで日本語に翻訳しました。
Go 1.23 Release Notes
Go 1.23の紹介
最新のGoリリースであるバージョン1.23は、前バージョン1.22のリリースから6か月後に公開されました。このリリースの変更点の多くは、ツールチェーン、ランタイム、ライブラリの実装に関するものです。これまでと同様に、Go 1の互換性ポリシーが維持されており、ほとんどのGoプログラムはこれまで通りコンパイルおよび実行できると予想されます。
言語の変更
for-range
ループ内のrange
句で、以下の型のイテレータ関数がrange
式として使用できるようになりました。
|
|
上記のようなイテレータ関数の呼び出しは、for-range
ループのイテレーション値を生成します。
詳細については、iterパッケージのドキュメント
、言語仕様
、およびRange over Function Typesブログ記事
を参照してください。
導入の動機については、2022年の“range-over-func”ディスカッションをご覧ください。
Go 1.23には、ジェネリック型エイリアスのプレビューサポートが含まれています。
この機能は、GOEXPERIMENT=aliastypeparams
を設定してツールチェーンをビルドすることで、パッケージ内で有効化できます。
現時点では、パッケージ間でジェネリック型エイリアスを使用することはサポートされていません。
ツール
テレメトリ
Go 1.23から、Goツールチェーンは使用状況や問題に関する統計を収集できるようになりました。
この統計情報は、Goツールチェーンがどのように使用され、どの程度正常に動作しているかをGoチームが理解するのに役立ちます。
この統計情報を「Goテレメトリ」と呼びます。
Goテレメトリは、go telemetry
コマンドで制御されるオプトインシステムです。
デフォルトでは、ツールチェーンプログラムは統計情報をカウンタファイルに収集し、ローカルで確認できますが、それ以外には使用されません(go telemetry local
モード)。
Goの正常な動作を維持し、使用状況を理解するため、go telemetry on
を実行してGoテレメトリに参加することをご検討ください。
このモードでは、匿名のカウンタレポートが毎週telemetry.go.dev
にアップロードされ、グラフとして集計されます。
このデータは、Goのコントリビューターやデータを分析したいユーザーがダウンロードして利用できます。
詳細は「Go Telemetry
」を参照してください。
Goコマンド
Go 1.23では、いくつかのGoコマンドに新しい機能が追加されています。
まず、環境変数GOROOT_FINAL
の設定はもはや効果を持たなくなりました。
ツールチェーンを$GOROOT/bin/go
以外の場所にインストールするディストリビューションは、バイナリを移動またはコピーするのではなく、シンボリックリンクを使用することが推奨されます。
新たに追加されたgo env -changed
フラグは、現在の環境設定の中でデフォルト値から変更されているもののみを表示します。
これにより、環境設定を効率的に確認できるようになりました。
また、go mod tidy -diff
フラグが追加され、go mod tidy
コマンドがファイルを実際に変更する代わりに、必要な変更内容を統一差分形式(unified diff)で表示します。
このフラグは、更新が必要な場合に非ゼロの終了コードを返します。
さらに、go list -m -json
コマンドに新たなSum
およびGoModSum
フィールドが追加されました。
この拡張は、既存のgo mod download -json
コマンドの動作に類似しています。
また、go.mod
やgo.work
ファイルに新しいgodebug
ディレクティブが導入され、使用中の作業モジュールやワークスペースに適用するGODEBUG
設定を宣言できるようになりました。
Vet
go vet
サブコマンドには、新しいstdversion
アナライザーが追加されました。
このアナライザーは、参照元のファイルで指定されたGoバージョンに対して新しすぎるシンボルへの参照を検出します。
適用されるGoのバージョンは、そのファイルを含むgo.mod
ファイルのgo
ディレクティブおよびファイル内の//go:build
制約によって決定されます。
例えば、reflect.TypeFor
関数(Go 1.22で導入)がgo.mod
ファイルでgo 1.21
を指定しているモジュール内のファイルで参照された場合、診断結果として報告されます。
Cgo
cmd/cgo
では、新しい-ldflags
フラグがサポートされるようになりました。このフラグは、Cリンカにフラグを渡すために使用されます。
go
コマンドはこれを自動的に利用し、大量のCGO_LDFLAGS
を使用した場合の「引数リストが長すぎる」というエラーを回避します。
Trace
trace
ツールは、部分的に破損したトレースデータをより適切に処理できるようになりました。
可能な限りトレースデータを復元しようと試みます。この機能は特にプログラムのクラッシュ中に収集されたトレースを表示する際に役立ちます。
クラッシュ直前までのトレースデータがほとんどの場合復元可能になります。
Runtime
未処理のパニックやその他の致命的なエラーの後にランタイムが出力するトレースバックは、エラーメッセージ(例えばpanic
の引数)の2行目以降を1タブ分インデントするようになりました。
この変更により、エラーメッセージが最初のゴルーチンのスタックトレースと明確に区別できるようになります。この変更についての詳細は#64590
を参照してください。
コンパイラ
Go 1.23では、プロファイルガイド最適化(PGO)を有効にしたビルド時のオーバーヘッドが大幅に削減されました。
以前は、大規模なビルドでPGOを有効化するとビルド時間が100%以上増加することがありましたが、Go 1.23では、オーバーヘッドが数パーセントに抑えられています。
また、Go 1.23のコンパイラでは、関数内の異なる領域でアクセスされるローカル変数のスタックフレームスロットを重ねて使用できるようになり、Goアプリケーションのスタック使用量が削減されます。
さらに、386およびamd64において、PGOの情報を利用してループ内の特定のホットブロックをアラインメントするようになりました。
これにより、パフォーマンスが1~1.5%向上し、テキストサイズとバイナリサイズが0.1%増加するというコストが伴います。
この機能は現在386とamd64でのみ実装されており、他のプラットフォームでは効果が確認されていません。
ホットブロックアラインメントは、-gcflags=[<packages>=]-d=alignhot=0
で無効にすることができます。
リンカ
リンカでは、定義に//go:linkname
が指定されていない標準ライブラリ(ランタイムを含む)の内部シンボルを、//go:linkname
ディレクティブを使用して参照することが禁止されました。
同様に、アセンブリコードからこれらのシンボルを参照することも禁止されます。
ただし、後方互換性のため、オープンソースのコードベースで既に存在している//go:linkname
の使用は引き続きサポートされます。
新しい標準ライブラリの内部シンボルへの参照はすべて禁止されます。
デバッグや実験の目的で、このチェックを無効化するためのリンカコマンドラインフラグ-checklinkname=0
が利用可能です。
また、動的リンクされたELFバイナリ(PIEバイナリを含む)をビルドする際に、新しい-bindnow
フラグを使用すると、関数の即時バインディングが有効になります。
標準ライブラリ
タイマーの変更
Go 1.23では、time.Timer
とtime.Ticker
の実装に2つの大きな変更が加えられました。
1つ目は、プログラムによって参照されなくなったタイマーやティッカーが、Stop
メソッドが呼び出されていなくても即座にガベージコレクションの対象になるようになったことです。
これまでのGoのバージョンでは、Stop
されていないTimer
は発火後まで収集されず、Ticker
は決して収集されませんでした。
2つ目は、タイマーやティッカーに関連付けられたチャンネルが非バッファ型(容量0)になったことです。
この変更の主な効果は、Reset
やStop
メソッドが呼び出された際、それ以前に準備された古い値がその後に送信または受信されることがないという保証が得られることです。
以前のGoバージョンでは、1要素のバッファを持つチャンネルを使用していたため、Reset
やStop
を正しく使用するのが困難でした。
この変更により、タイマーチャンネルのlen
やcap
は0を返すようになり、以前は1を返していたため、この値をポーリングして受信が成功するかを判断するコードに影響する可能性があります。
そのようなコードは、非ブロック型の受信を使用するように変更するべきです。
これらの新しい動作は、メインのGoプログラムがgo.mod
ファイルでgo 1.23.0
以降を指定している場合にのみ有効になります。
Go 1.23で古いプログラムをビルドする場合、以前の動作がそのまま適用されます。
また、新しいGODEBUG
設定asynctimerchan=1
を使用すると、プログラムがgo 1.23.0
以降を指定している場合でも非同期チャンネル動作に戻すことが可能です。
新しい unique パッケージ
新しいunique
パッケージは、値を正規化(例えば、「インターン」や「ハッシュコンシング」)する機能を提供します。
比較可能な型の任意の値を、新しいMake[T]
関数を使って正規化することができます。
この関数は、Handle[T]
という形式で値の正規化コピーへの参照を生成します。
2つのHandle[T]
は、生成元の値が等しい場合にのみ等しいと判断されるため、プログラムは値を重複排除してメモリ使用量を削減することができます。
2つのHandle[T]
値を比較するのは効率的で、単純なポインタ比較に還元されます。
イテレータ
新しいiterパッケージは、ユーザー定義のイテレータを操作するための基本的な定義を提供します。
slicesパッケージでは、イテレータと連携する以下の関数が追加されています。
- All: スライスのインデックスと値に対するイテレータを返します。
- Values: スライス要素に対するイテレータを返します。
- Backward: スライスを逆順にループするイテレータを返します。
- Collect: イテレータから値を収集して新しいスライスを生成します。
- AppendSeq: イテレータから値を収集し、既存のスライスに追加します。
- Sorted: イテレータから値を収集して新しいスライスを生成し、そのスライスをソートします。
- SortedFunc: Sortedと同様ですが、比較関数を使用してソートします。
- SortedStableFunc: SortedFuncと似ていますが、安定ソートアルゴリズムを使用します。
- Chunk: スライスを連続するn個の要素ごとに分割した部分スライスに対するイテレータを返します。
mapsパッケージでは、イテレータと連携する以下の関数が追加されています。
- All: マップからキーと値のペアに対するイテレータを返します。
- Keys: マップ内のキーに対するイテレータを返します。
- Values: マップ内の値に対するイテレータを返します。
- Insert: イテレータから取得したキーと値のペアを既存のマップに追加します。
- Collect: イテレータからキーと値のペアを収集して新しいマップを生成し、それを返します。
新しいstructsパッケージ
新しいstructsパッケージは、構造体フィールドに対する型を提供します。この型は、メモリレイアウトなど、構造体型のプロパティを変更します。
このリリースでは、唯一の型としてHostLayoutが追加されました。
HostLayoutは、この型を持つフィールドを持つ構造体が、ホストプラットフォームの期待に一致するレイアウトであることを示します。
この型は、ホストAPIに渡される、またはホストAPIから返されるポインタを介してアクセスされる型で使用されるべきです。
このマーカーがない場合、言語仕様では構造体のレイアウト順序が保証されません。ただし、Go 1.23の時点では、ホストのレイアウトとGo言語のレイアウトは一致しています。
ライブラリの細かい変更
archive/tar
FileInfoHeaderの引数が新しいFileInfoNamesインターフェースを実装している場合、そのインターフェースメソッドが使用されてファイルヘッダーのUname/Gnameが設定されます。
これにより、アプリケーションはシステム依存のUname/Gnameの検索を上書きすることが可能になります。
crypto/tls
TLSクライアントがEncrypted Client Helloドラフト仕様をサポートするようになりました。
この機能は、Config.EncryptedClientHelloConfigListフィールドに接続対象のホスト用のエンコードされたECHConfigListを設定することで有効にできます。
QUIC実装で使用されるQUICConn型に、新しいセッション再開の状態に関するイベントが追加され、QUICレイヤーがセッションチケットやセッションキャッシュエントリにデータを追加する方法を提供します。
3DES暗号スイートは、Config.CipherSuitesがnilのときに使用されるデフォルトリストから削除されました。
このデフォルトは、GODEBUG環境変数にtls3des=1
を追加することで復元できます。
実験的なポスト量子鍵交換メカニズムX25519Kyber768Draft00は、Config.CurvePreferencesがnilの場合にデフォルトで有効になりました。
このデフォルトは、GODEBUG環境変数にtlskyber=0
を追加することで無効にできます。
Go 1.23では、X509KeyPairおよびLoadX509KeyPairの動作が変更され、返されるCertificateのCertificate.Leafフィールドが埋められるようになりました。
この動作に関連する新しいGODEBUG設定x509keypairleaf
が追加されました。
crypto/x509
CreateCertificateRequestは、RSA-PSS署名アルゴリズムを正しくサポートするようになりました。
CreateCertificateRequestおよびCreateRevocationListは、生成された署名を署名者の公開鍵を使用して検証するようになりました。
署名が無効な場合はエラーが返されます。この挙動は、Go 1.16以降のCreateCertificateと同様です。
GODEBUG設定x509sha1
は、次のGoメジャーリリース(Go 1.24)で削除されます。
これにより、crypto/x509はSHA-1ベースの署名アルゴリズムを使用する証明書の署名検証をサポートしなくなります。
新しいParseOID関数が追加され、ドットで区切られたASN.1オブジェクト識別子(OID)文字列を解析できるようになりました。
また、OID型はencoding.BinaryMarshaler、encoding.BinaryUnmarshaler、encoding.TextMarshaler、encoding.TextUnmarshalerの各インターフェースを実装しました。
database/sql
driver.Valuerの実装が返すエラーは、DB.Query、DB.Exec、DB.QueryRowなどの操作中にエラーハンドリングを改善するためにラップされるようになりました。
debug/elf
debug/elfパッケージに、PT_OPENBSD_NOBTCFIが定義されました。
このProgTypeは、OpenBSDバイナリでブランチトラッキング制御フロー整合性(BTCFI)の適用を無効にするために使用されます。
また、新しいシンボルタイプ定数としてSTT_RELC、STT_SRELC、およびSTT_GNU_IFUNCが定義されました。
encoding/binary
新しいEncodeおよびDecode関数が追加され、これらはReadおよびWriteのバイトスライスに対応する機能を提供します。
また、Append関数を使用することで、複数のデータを同じバイトスライスにマーシャリングすることが可能になります。
go/ast
新しいPreorder関数が追加され、構文木内のすべてのノードを簡単に反復処理できるイテレータを返すようになりました。
go/types
Func型(関数またはメソッドのシンボルを表す)に新しいFunc.Signatureメソッドが追加されました。このメソッドは常にSignature型を返します。
Alias型には、新たにRhsメソッドが追加されました。このメソッドは宣言の右辺にある型を返します。たとえば、type A = B
と宣言されている場合、AのRhsはBです。
また、Alias型にはAlias.Origin、Alias.SetTypeParams、Alias.TypeParams、Alias.TypeArgsといった新しいメソッドが追加されました。
これらはジェネリック型エイリアスに必要です。
デフォルトでは、go/typesは型エイリアスに対してAlias型ノードを生成するようになりました。この挙動は、GODEBUG gotypesaliasフラグで制御できます。
このフラグのデフォルト値は、Go 1.22の0からGo 1.23では1に変更されました。
math/rand/v2
Uint関数およびRand.Uintメソッドが追加されました。これらはGo 1.22で誤って除外されていたものです。
新しいChaCha8.Readメソッドが追加され、io.Readerインターフェースを実装しています。
net
新しいKeepAliveConfig型が追加され、TCP接続のキープアライブオプションを細かく調整できるようになりました。
これには新しいTCPConn.SetKeepAliveConfigメソッドや、DialerとListenConfig用のKeepAliveConfigフィールドが含まれます。
DNSError型は、タイムアウトやキャンセルによるエラーをラップするようになりました。
たとえば、errors.Is(someDNSErr, context.DeadlineExceeded)
は、DNSエラーがタイムアウトによって引き起こされたかどうかを報告するようになりました。
新しいGODEBUG設定netedns0=0
を使用すると、DNSリクエストでEDNS0追加ヘッダーの送信を無効化できます。
一部のモデムでDNSサーバーが正常に動作しなくなることが報告されているためです。
net/http
Cookieは、値を囲む二重引用符を保持するようになりました。また、新しいCookie.Quotedフィールドは、Cookie.Valueが元々引用されていたかを示します。
新しいRequest.CookiesNamedメソッドは、指定した名前に一致するすべてのクッキーを取得します。
新しいCookie.Partitionedフィールドは、Partitioned属性を持つクッキーを識別します。
ServeMuxのパターンでは、メソッド名の後に1つ以上のスペースやタブを許可するようになりました。以前は1つのスペースのみ許可されていました。
新しいParseCookie関数は、Cookieヘッダーの値を解析し、設定されたすべてのクッキーを返します。
同じ名前のクッキーが複数回設定される場合、返されるValuesには1つのキーに複数の値が含まれることがあります。
新しいParseSetCookie関数は、Set-Cookieヘッダーの値を解析し、クッキーを返します。構文エラーの場合にはエラーを返します。
ServeContent、ServeFile、およびServeFileFSは、エラーを提供する際にCache-Control、Content-Encoding、Etag、Last-Modifiedヘッダーを削除するようになりました。
これらのヘッダーは通常、エラーではなく通常のコンテンツに適用されるものです。
レスポンスをラップし、動的エンコーディング(例:Content-Encoding: gzip)を適用するミドルウェアは、この変更後に動作しなくなります。
以前のServeContent、ServeFile、ServeFileFSの動作は、GODEBUG=httpservecontentkeepheaders=1
を設定することで復元できます。
なお、ServeContentがRangeリクエストを処理する場合、提供するコンテンツのサイズを変更する(例:圧縮)ミドルウェアはすでに正しく動作していません。
動的な圧縮は、Content-Encodingの代わりにTransfer-Encodingヘッダーを使用する必要があります。
受信リクエストの場合、新しいRequest.Patternフィールドにはリクエストに一致したServeMuxのパターンが含まれます。
ただし、GODEBUG=httpmuxgo121=1
が設定されている場合、このフィールドは設定されません。
net/http/httptest
新しいNewRequestWithContextメソッドが追加され、context.Contextを持つ受信リクエストを作成できるようになりました。
net/netip
Go 1.22以前では、reflect.DeepEqualを使用してIPv4アドレスを保持するAddrと、そのIPv4アドレスのIPv6マッピング形式を保持するAddrを比較した場合、Addr値が異なるにもかかわらず誤ってtrueを返していました。このバグは修正され、==演算子やAddr.Compareでの比較結果と一致するようになりました。
os
Stat関数は、Windows上でUnixソケットであるファイルに対してModeSocketビットを設定するようになりました。
これらのファイルは、IO_REPARSE_TAG_AF_UNIXというリパースタグを持つことで識別されます。
Windows上で、LstatおよびStatがリパースポイントのモードビットを報告する方法が変更されました。
マウントポイントはもはやModeSymlinkを持たず、シンボリックリンクでもUnixソケットでも重複排除ファイルでもないリパースポイントは常にModeIrregularを持つようになりました。
この動作はwinsymlink設定によって制御されます。Go 1.23では、デフォルトでwinsymlink=1に設定されていますが、以前のバージョンではwinsymlink=0がデフォルトでした。
CopyFS関数が追加され、io/fs.FSをローカルファイルシステムにコピーできるようになりました。
Windows上では、Readlinkがボリュームをドライブ文字に正規化しようとしなくなりました。この正規化は常に可能であるとは限らなかったためです。
この動作はwinreadlinkvolume設定によって制御されます。
Go 1.23ではデフォルトでwinreadlinkvolume=1が有効になっていますが、以前のバージョンではwinreadlinkvolume=0がデフォルトでした。
Linuxでpidfdをサポートしている場合(一般にLinux v5.4以上)、Process関連の関数やメソッドは内部的にPIDではなくpidfdを使用するようになりました。
これにより、OSがPIDを再利用した際の誤ったターゲットを排除できます。
pidfdサポートはユーザーに完全に透過的ですが、プロセスが追加のファイルディスクリプタを持つ場合があります。
path/filepath
新しいLocalize関数が追加され、スラッシュ区切りのパスを安全にオペレーティングシステムのパス形式に変換できるようになりました。
Windowsでは、EvalSymlinksがマウントポイントを評価しなくなりました。この変更は、一貫性やバグの問題を多く引き起こしていた挙動を修正したものです。
この動作はwinsymlink設定によって制御されます。
Go 1.23ではデフォルトでwinsymlink=1に設定されていますが、以前のバージョンではwinsymlink=0がデフォルトでした。
また、Windowsでは、EvalSymlinksがボリュームをドライブ文字に正規化しようとしなくなりました。
この正規化は常に可能であるとは限りませんでした。この動作はwinreadlinkvolume設定によって制御されます。
Go 1.23ではデフォルトでwinreadlinkvolume=1が有効になっていますが、以前のバージョンではwinreadlinkvolume=0がデフォルトでした。
reflect
新しいメソッドがTypeに追加されました。これらはValueに同名のメソッドと同様の機能を提供します。
- Type.OverflowComplex
- Type.OverflowFloat
- Type.OverflowInt
- Type.OverflowUint
新しいSliceAt関数が追加されました。これはNewAt関数に類似していますが、スライス用に設計されています。
Value.PointerとValue.UnsafePointerメソッドは、kindがStringの値をサポートするようになりました。
新しいメソッドValue.SeqとValue.Seq2が追加されました。これらは値をfor/rangeループで使用するかのように反復処理するシーケンスを返します。
また、新しいType.CanSeqとType.CanSeq2メソッドは、それぞれValue.SeqおよびValue.Seq2を呼び出した際にパニックせずに成功するかどうかを報告します。
runtime/debug
SetCrashOutput関数が追加され、ランタイムが致命的なクラッシュレポートを書き込む代替ファイルを指定できるようになりました。
この機能は、goroutineで明示的にrecoverを使用していない場合も含め、すべての予期しないクラッシュに対して自動的なレポートメカニズムを構築するために使用できます。
runtime/pprof
alloc、mutex、block、threadcreate、およびgoroutineプロファイルの最大スタック深度が32フレームから128フレームに引き上げられました。
runtime/trace
ランタイムは、未処理のパニックによってプログラムがクラッシュした場合に、トレースデータを明示的にフラッシュするようになりました。
この変更により、トレースがアクティブな状態でプログラムがクラッシュした場合、より完全なトレースデータが利用可能になります。
slices
新しいRepeat関数が追加され、指定されたスライスを指定された回数だけ繰り返す新しいスライスを返します。
sync
Map型にClearメソッドが追加されました。このメソッドはすべてのエントリを削除し、空のMapを生成します。これはclearに類似した動作をします。
sync/atomic
新しいAndおよびOr演算子が追加されました。これらは、入力に対してビットごとのANDまたはORを適用し、古い値を返します。
syscall
syscallパッケージに、Windowsで使用されるWSAENOPROTOOPT定数が定義されました。
WindowsでGetsockoptInt関数がサポートされるようになりました。
testing/fstest
TestFS関数は、構造化されたエラーを返すようになりました。このエラーは、Unwrap() []error
メソッドを使用して展開できます。
これにより、errors.Isやerrors.Asを使用してエラーを検査することが可能になります。
text/template
テンプレートで新しい「else with」アクションがサポートされました。これにより、一部のユースケースでテンプレートの複雑さが軽減されます。
time
ParseおよびParseInLocation関数は、タイムゾーンのオフセットが範囲外の場合にエラーを返すようになりました。
Windowsでは、Timer、Ticker、およびSleepのようにgoroutineをスリープ状態にする関数の時間分解能が、従来の15.6msから0.5msに改善されました。
unicode/utf16
RuneLen関数が追加され、ルーンをUTF-16でエンコードした場合の16ビットワード数を返します。ルーンがUTF-16でエンコードできない無効な値の場合は、-1を返します。
サポート環境
Darwin
Go 1.22のリリースノートで発表された通り、Go 1.23はmacOS 11 Big Sur以降を必要とし、それ以前のバージョンのサポートは終了しました。
Linux
Go 1.23は、Linuxカーネルバージョン2.6.32以降を必要とする最後のリリースです。Go 1.24では、Linuxカーネルバージョン3.2以降が必要になります。
OpenBSD
Go 1.23は、64ビットRISC-V(GOOS=openbsd, GOARCH=riscv64)上のOpenBSDに対する実験的なサポートを追加しました。
ARM64
Go 1.23では、新しい環境変数GOARM64が導入されました。この変数は、コンパイル時にARM64アーキテクチャの最低ターゲットバージョンを指定します。指定可能な値はv8.{0-9}
およびv9.{0-5}
です。ターゲットハードウェアが実装する拡張機能を指定するオプションとして、,lse
および,crypto
が有効です。
GOARM64のデフォルト値はv8.0
です。
RISC-V
Go 1.23では、新しい環境変数GORISCV64が導入されました。この変数は、コンパイルするRISC-Vのユーザーモードアプリケーションプロファイルを選択します。指定可能な値はrva20u64
およびrva22u64
です。
GORISCV64のデフォルト値はrva20u64
です。
Wasm
GOROOT/misc/wasmにあるgo_wasip1_wasm_exec
スクリプトは、wasmtimeバージョン14.0.0未満のサポートを終了しました。