前書き
Go 1.3のリリースノートをChatGPTで日本語に翻訳しました。
Go 1.3 Release Notes
次のバージョン:Go1.4のリリースノート(日本語訳)
前のバージョン:Go1.2のリリースノート(日本語訳)
リリースノート一覧:Goリリース情報
Go 1.3の紹介
最新のGoリリースであるバージョン1.3は、1.2の6か月後に登場し、言語の変更はありません。
主に実装作業に焦点を当てており、正確なガベージコレクション、
コンパイラツールチェーンの大規模なリファクタリングにより、
特に大規模プロジェクトでのビルドが高速化され、
全体的なパフォーマンスの大幅な向上、
DragonFly BSD、Solaris、Plan 9、GoogleのNative Clientアーキテクチャ(NaCl)のサポートを提供します。
また、同期に関するメモリモデルの重要な改良も含まれています。
いつものように、Go 1.3は互換性の約束
を守り、
ほとんどすべてが1.3に移行しても変更なしにコンパイルおよび実行を続けることができます。
サポートされるオペレーティングシステムとアーキテクチャの変更
Windows 2000のサポートの削除
Microsoftは2010年にWindows 2000のサポートを終了しました。
例外処理(Unixの用語ではシグナル)に関する実装の困難
があるため、
Go 1.3以降、Goでもサポートされなくなりました。
DragonFly BSDのサポート
Go 1.3では、amd64(64ビットx86)および386(32ビットx86)アーキテクチャでのDragonFly BSDの実験的サポートが含まれています。
DragonFly BSD 3.6以上を使用します。
FreeBSDのサポート
当時は発表されていませんでしたが、Go 1.2のリリース以降、FreeBSDでのGoのサポートにはFreeBSD 8以上が必要です。
Go 1.3では、FreeBSDでのGoのサポートには、カーネルがCOMPAT_FREEBSD32
フラグを設定してコンパイルされている必要があります。
ARMプラットフォーム用のEABIシステムコールへの切り替えに伴い、Go 1.3はFreeBSD 10でのみ動作します。
x86プラットフォーム、386およびamd64には影響はありません。
Native Clientのサポート
Native Client仮想マシンアーキテクチャのサポートがGo 1.3リリースで復活しました。
32ビットIntelアーキテクチャ(GOARCH=386
)および64ビットIntelでも動作しますが、32ビットポインタを使用します(GOARCH=amd64p32
)。
ARMでのNative Clientのサポートはまだありません。
これはNative Client(NaCl)であり、Portable Native Client(PNaCl)ではないことに注意してください。
Native Clientの詳細はこちら
にあります。
Goバージョンのセットアップ方法はこちら
に記載されています。
NetBSDのサポート
Go 1.3以降、NetBSDでのGoのサポートにはNetBSD 6.0以上が必要です。
OpenBSDのサポート
Go 1.3以降、OpenBSDでのGoのサポートにはOpenBSD 5.5以上が必要です。
Plan 9のサポート
Go 1.3では、386(32ビットx86)アーキテクチャでのPlan 9の実験的サポートが含まれています。
これは、2012年6月以降Plan 9に含まれているTsemacquire
システムコールを必要とします。
Solarisのサポート
Go 1.3では、amd64(64ビットx86)アーキテクチャでのSolarisの実験的サポートが含まれています。
これは、illumos、Solaris 11以上を必要とします。
メモリモデルの変更
Go 1.3のメモリモデルは、バッファ付きチャネルでの送信と受信に関する新しいルールを追加
し、
バッファ付きチャネルが単純なセマフォとして使用できることを明示しています。
これは言語の変更ではなく、通信の期待される特性についての明確化です。
実装とツールの変更
スタック
Go 1.3では、ゴルーチンスタックの実装が古い「セグメント化」モデルから連続モデルに変更されました。
ゴルーチンが利用可能なスタック以上のスタックを必要とする場合、そのスタックはより大きな単一のメモリブロックに転送されます。
この転送操作のオーバーヘッドはうまく償却され、計算がセグメント境界を繰り返し越える際の古い「ホットスポット」問題を解消します。
詳細とパフォーマンスの数値はこの設計文書
にあります。
ガベージコレクタの変更
しばらくの間、ガベージコレクタはヒープ内の値を調べる際に正確でしたが、Go 1.3リリースではスタック上の値にも同等の精度が追加されました。
これにより、整数のような非ポインタGo値がポインタと誤解され、未使用メモリの回収を妨げることはありません。
Go 1.3以降、ランタイムはポインタ型の値がポインタを含み、他の値は含まないと仮定します。
この仮定は、スタック拡張とガベージコレクションの両方の正確な動作にとって基本的です。
package unsafe
を使用してポインタ型の値に整数を格納するプログラムは違法であり、
ランタイムがその動作を検出するとクラッシュします。
package unsafe
を使用して整数型の値にポインタを格納するプログラムも違法ですが、
実行中に診断するのはより困難です。
ポインタがランタイムから隠されているため、スタック拡張やガベージコレクションが
それらが指すメモリを回収し、ダングリングポインタ
を作成する可能性があります。
更新: メモリに保持されている整数型の値をポインタに変換するためにunsafe.Pointer
を使用するコードは違法であり、
書き直す必要があります。
そのようなコードはgo vet
によって識別できます。
マップのイテレーション
小さなマップに対するイテレーションはもはや一貫した順序で行われません。
Go 1は「マップのイテレーション順序は指定されておらず、次のイテレーションで同じであることは保証されていません。
」と定義しています。
マップのイテレーション順序に依存するコードを防ぐために、
Go 1.0は各マップイテレーションをマップ内のランダムなインデックスから開始しました。
Go 1.1で導入された新しいマップ実装は、8つ以下のエントリを持つマップのイテレーションをランダム化しませんでしたが、
イテレーション順序はシステムによって異なる可能性があります。
これにより、小さなマップのイテレーション順序に依存し、特定のシステムでのみ信頼性を持って動作するGo 1.1およびGo 1.2プログラムを書くことができました。
Go 1.3はこれらのバグを排除するために小さなマップのランダムイテレーションを再導入します。
更新: 小さなマップの固定イテレーション順序を仮定するコードは壊れ、
その仮定をしないように書き直す必要があります。
小さなマップのみが影響を受けるため、問題は主にテストで発生します。
リンカ
Goリンカの一般的なオーバーホール
の一環として、
コンパイラとリンカがリファクタリングされました。
リンカはまだCプログラムですが、リンカの一部であった命令選択フェーズが
liblink
という新しいライブラリの作成を通じてコンパイラに移動されました。
命令選択をパッケージが最初にコンパイルされたときに一度だけ行うことで、
大規模プロジェクトのコンパイルを大幅に高速化できます。
更新: これは主要な内部変更ですが、プログラムには影響を与えないはずです。
gccgoのステータス
GCCリリース4.9にはGo 1.2(1.3ではない)バージョンのgccgoが含まれます。
GCCとGoプロジェクトのリリーススケジュールは一致していないため、
1.3は開発ブランチで利用可能になりますが、
次のGCCリリース4.10にはおそらくGo 1.4バージョンのgccgoが含まれるでしょう。
goコマンドの変更
cmd/go
コマンドにはいくつかの新機能があります。
go run
および
go test
サブコマンドは、
結果のバイナリを実行するための代替方法を指定する新しい-exec
オプションをサポートしています。
その即時の目的はNaClをサポートすることです。
go test
サブコマンドのテストカバレッジサポートは、
レースデテクタが有効になっている場合にカバレッジモードを-atomic
に自動的に設定し、
カバレッジカウンタへの安全でないアクセスに関する誤報を排除します。
go test
サブコマンドは、
テストファイルがない場合でも常にパッケージをビルドします。
以前は、テストファイルが存在しない場合は何もしませんでした。
go build
サブコマンドは、
指定されたターゲットの依存関係をインストールするがターゲット自体はインストールしない新しい-i
オプションをサポートしています。
cgo
が有効な状態でのクロスコンパイルがサポートされるようになりました。
CC_FOR_TARGET
およびCXX_FOR_TARGET
環境変数は、
all.bash
を実行する際にCおよびC++コードのクロスコンパイラを指定するために使用されます。
最後に、go
コマンドはcgo
を通じてObjective-Cファイル(拡張子.m
)をインポートするパッケージをサポートするようになりました。
cgoの変更
cmd/cgo
コマンドは、
Goパッケージ内のimport "C"
宣言を処理し、
いくつかのパッケージがコンパイルを停止する可能性のある重大なバグを修正しました。
以前は、不完全な構造体型へのすべてのポインタがGo型*[0]byte
に変換され、
Goコンパイラがある種の構造体ポインタを別の関数に渡すことを診断できませんでした。
Go 1.3はこの誤りを修正し、異なる不完全な構造体を異なる名前付き型に変換します。
不完全な構造体S
のC宣言typedef struct S T
が与えられた場合、
一部のGoコードはこのバグを使用して型C.struct_S
とC.T
を互換的に参照していました。
cgo
はこの使用を明示的に許可していますが、完了した構造体型でも同様です。
ただし、一部のGoコードはこのバグを使用して(たとえば)*C.FILE
を
あるパッケージから別のパッケージに渡すこともありました。
これは合法ではなく、もはや機能しません:一般にGoパッケージはAPIでC型や名前を公開することを避けるべきです。
更新: 不完全な型へのポインタを混同したり、
それらをパッケージ境界を越えて渡すコードはもはやコンパイルされず、
書き直す必要があります。
変換が正しく、保持する必要がある場合は、
unsafe.Pointer
を介した明示的な変換を使用してください。
SWIGを使用するプログラムにはSWIG 3.0が必要
SWIGを使用するGoプログラムには、SWIGバージョン3.0が必要です。
cmd/go
コマンドは、
SWIGが生成したオブジェクトファイルを直接バイナリにリンクするようになり、
共有ライブラリでビルドおよびリンクするのではなくなりました。
コマンドラインフラグの解析
gc
ツールチェーンでは、アセンブラがGoフラグパッケージと同じコマンドラインフラグ解析ルールを使用するようになり、
従来のUnixフラグ解析からの逸脱となります。
これにより、ツールを直接呼び出すスクリプトに影響を与える可能性があります。
たとえば、
go tool 6a -SDfoo
は
go tool 6a -S -D foo
と書く必要があります。
(同じ変更がGo 1.1
でコンパイラとリンカにも行われました。)
godocの変更
-analysis
フラグを指定して呼び出すと、
godoc
は
インデックス化するコードの高度な静的解析を行います。
解析結果はソースビューとパッケージドキュメントビューの両方で表示され、
各パッケージの呼び出しグラフや、
定義と参照の関係、
型とそのメソッド、
インターフェースとその実装、
チャネルでの送信と受信操作、
関数とその呼び出し元、
呼び出しサイトとその呼び出し先を含みます。
その他
ベンチマーク実行間のパフォーマンスを比較するプログラムmisc/benchcmp
が書き直されました。
以前はメインリポジトリのシェルとawk
スクリプトでしたが、現在はgo.tools
リポジトリのGoプログラムです。
ドキュメントはこちら
にあります。
Goディストリビューションをビルドする少数の人々のために、ツールmisc/dist
が移動および改名されました。
現在はメインリポジトリのmisc/makerelease
にあります。
パフォーマンス
このリリースのGoバイナリのパフォーマンスは、ランタイムとガベージコレクションの変更、
およびいくつかのライブラリの変更により、多くの場合で改善されています。
重要な例としては以下があります:
ランタイムはdefer
をより効率的に処理し、defer
を呼び出すゴルーチンごとに約2キロバイトのメモリフットプリントを削減します。
ガベージコレクタは、並行スイープアルゴリズム、より良い並列化、および大きなページを使用して高速化されました。
累積効果として、コレクタの停止時間が50〜70%削減されることがあります。
レースデテクタ(このガイド
を参照)は約40%高速化されました。
正規表現パッケージregexp
は、特定の単純な式に対して大幅に高速化されました。
これは、2番目のワンパス実行エンジンの実装によるものです。
どのエンジンを使用するかの選択は自動であり、
詳細はユーザーから隠されています。
また、ランタイムはスタックダンプにゴルーチンがブロックされている時間を含めるようになり、
デッドロックやパフォーマンスの問題をデバッグする際に役立つ情報を提供します。
標準ライブラリの変更
新しいパッケージ
新しいパッケージdebug/plan9obj
が標準ライブラリに追加されました。
これはPlan 9のa.out
オブジェクトファイルへのアクセスを実装します。
ライブラリの主要な変更
crypto/tls
の以前のバグにより、
TLSでの検証を意図せずにスキップすることが可能でした。
Go 1.3では、このバグが修正されました:ServerName
またはInsecureSkipVerify
のいずれかを指定する必要があり、
ServerName
が指定されている場合は強制されます。
これは、不正な動作に依存していた既存のコードを壊す可能性があります。
標準ライブラリに重要な新しい型が追加されました:sync.Pool
です。
これは、メモリがシステムによって自動的に回収される特定のタイプのキャッシュを効率的に実装するメカニズムを提供します。
testing
パッケージのベンチマークヘルパー、
B
には、
複数のCPUを使用するベンチマークを実行しやすくするための
RunParallel
メソッドが追加されました。
更新: crypto/tls
の修正は既存のコードを壊す可能性がありますが、
そのようなコードは誤っており、更新されるべきです。
ライブラリの小さな変更
以下のリストは、ライブラリへのいくつかの小さな変更、主に追加をまとめたものです。
各変更に関する詳細は、関連するパッケージのドキュメントを参照してください。
crypto/tls
新しいDialWithDialer 関数により、既存のダイアラを使用してTLS接続を確立できるようになり、タイムアウトなどのダイアルオプションを制御しやすくなりました。このパッケージはまた、接続に使用されたTLSバージョンをConnectionState 構造体で報告するようになりました。crypto/tls パッケージのCreateCertificate 関数は、PKCS #10証明書署名要求の解析(および他の場所でのシリアル化)をサポートするようになりました。
fmt
フォーマットされた印刷関数は、浮動小数点値を印刷する際に%F
を%f
の同義語として定義するようになりました。
math/big
Int
およびRat
型は、encoding.TextMarshaler
およびencoding.TextUnmarshaler
を実装するようになりました。
複素数のべき乗関数、Pow
は、最初の引数がゼロの場合の動作を指定するようになりました。以前は未定義でした。詳細は関数のドキュメント
にあります。
net/http
クライアントリクエストを行うために使用されるTLS接続のプロパティを新しいResponse.TLS
フィールドで公開するようになりました。net/http
パッケージは、オプションのサーバーエラーロガーをServer.ErrorLog
で設定できるようになりました。デフォルトは依然としてすべてのエラーが標準エラー出力に送られることです。
net/http
パッケージは、サーバーでのHTTPキープアライブ接続をServer.SetKeepAlivesEnabled
で無効にすることをサポートするようになりました。デフォルトは引き続き、サーバーがデフォルトでキープアライブ(複数のリクエストに対して接続を再利用)することです。リソースが制約されたサーバーや、優雅なシャットダウンを行っているサーバーのみがそれらを無効にすることを望むでしょう。
net/http
パッケージは、HTTPクライアントリクエストがTLSハンドシェイクの完了を待つ時間を制限するためのオプションのTransport.TLSHandshakeTimeout
設定を追加しました。これはデフォルトでも設定されるようになりましたDefaultTransport
で。
net/http
パッケージのDefaultTransport
は、HTTPクライアントコードで使用され、デフォルトでTCPキープアライブ
を有効にしました。Dial
フィールドがnil
の他のTransport
値は、以前と同じように機能し続けます:TCPキープアライブは使用されません。
net/http
パッケージは、ListenAndServe
またはListenAndServeTLS
が使用される場合、受信サーバーリクエストに対してTCPキープアライブ
を有効にしました。サーバーが他の方法で起動される場合、TCPキープアライブは有効になりません。
net/http
パッケージは、サーバー接続のライフサイクルのさまざまなフェーズにフックするためのオプションのServer.ConnState
コールバックを提供します(ConnState
を参照)。これは、レート制限や優雅なシャットダウンを実装するために使用できます。
net/http
パッケージのHTTPクライアントには、クライアントを使用して行われるリクエストに対してエンドツーエンドのタイムアウトを指定するためのオプションのClient.Timeout
フィールドがあります。
net/http
パッケージのRequest.ParseMultipartForm
メソッドは、ボディのContent-Type
がmultipart/form-data
でない場合にエラーを返すようになりました。Go 1.3以前は、黙って失敗し、nil
を返していました。以前の動作に依存しているコードは更新する必要があります。
net
Dialer
構造体に、接続のキープアライブ期間を指定するためのKeepAlive
オプションが追加されました。net/http
パッケージのTransport
は、エラーが発生した場合でもRequest.Body
を一貫して閉じるようになりました。
os/exec
バイナリの相対パスに関してドキュメントが常に述べていたことを実装するようになりました。特に、バイナリのファイル名にパスセパレータが含まれていない場合にのみLookPath を呼び出します。
reflect
SetMapIndex
関数は、nil
マップから削除する際にパニックを起こさなくなりました。メインゴルーチンがruntime.Goexit
を呼び出し、他のすべてのゴルーチンが実行を終了すると、プログラムは常にクラッシュし、検出されたデッドロックを報告します。以前のバージョンのGoでは、この状況を一貫して処理していませんでした:ほとんどのインスタンスはデッドロックとして報告されましたが、いくつかのトリビアルなケースはクリーンに終了しました。
runtime/debug
ヒープの説明を出力する新しい関数debug.WriteHeapDump が追加されました。
strconv
CanBackquote 関数は、DEL文字、U+007Fを非印刷として考慮するようになりました。
syscall
書き込まれたバイト数を返すSendmsg
の代替バージョンとしてSendmsgN
を提供するようになりました。Windowsでは、syscall
パッケージは、既存の関数NewCallback
に加えて、新しい関数NewCallbackCDecl
を追加することで、cdecl
呼び出し規約をサポートするようになりました。
testing
ほぼ常に誤っているpanic(nil)
を呼び出すテストを診断するようになりました。また、テストは失敗してもプロファイルを書き出すようになりました(プロファイリングフラグを指定して呼び出された場合)。
unicode
システム全体の関連サポートは、Unicode 6.2.0からUnicode 6.3.0 にアップグレードされました。