前書き
Go 1.9 のリリースノートをChatGPTで日本語に翻訳しました。
Go 1.9 Release Notes
次のバージョン:Go1.10のリリースノート(日本語訳)
前のバージョン:Go1.8のリリースノート(日本語訳)
リリースノート一覧:Goリリース情報
Go 1.9の紹介
最新のGoリリースであるバージョン1.9は、Go 1.8 の6か月後に登場し、Go 1.xシリーズ の10番目のリリースです。言語には2つの変更 があります。型エイリアスのサポートを追加し、実装が浮動小数点演算を融合できる場合を定義しています。ほとんどの変更はツールチェーン、ランタイム、およびライブラリの実装にあります。リリースは常にGo 1の互換性の約束 を維持しています。ほとんどのGoプログラムはこれまで通りにコンパイルおよび実行されることを期待しています。このリリースでは、透明な単調時間サポート 、パッケージ内の関数の並列コンパイル 、テストヘルパー関数 のサポートの向上、新しいビット操作パッケージ 、および新しい並行マップ型 が追加されています。
言語の変更
言語には2つの変更があります。Goは、型をパッケージ間で移動する際に段階的なコード修正をサポートするために型エイリアスをサポートするようになりました。型エイリアスの設計文書
とリファクタリングに関する記事
で問題が詳細に説明されています。簡単に言えば、型エイリアス宣言は次の形式を持ちます:
type T1 = T2
この宣言は、型T2
を示す別のスペルとしてエイリアス名T1
を導入します。つまり、T1
とT2
は同じ型を示します。小さな言語の変更として、言語仕様
は、実装が浮動小数点演算を融合できる場合を定義しています。たとえば、アーキテクチャの「融合乗算加算」(FMA
)命令を使用してx*y + z
を中間結果x*y
を丸めずに計算することができます。中間の丸めを強制するには、float64(x*y) + z
と書きます。
ポート
このリリースでは、新しいサポートされるオペレーティングシステムやプロセッサアーキテクチャはありません。
ppc64xはPOWER8を必要とします
GOARCH=ppc64
とGOARCH=ppc64le
は、今後は少なくともPOWER8のサポートが必要です。以前のリリースでは、GOARCH=ppc64le
のみがPOWER8を必要としており、ビッグエンディアンのppc64アーキテクチャは古いハードウェアをサポートしていました。
FreeBSD
Go 1.9は、FreeBSD 9.3で動作する最後のリリースです。これはすでにFreeBSDによってサポートされていません 。Go 1.10はFreeBSD 10.3以上を必要とします。
OpenBSD 6.0
Go 1.9は、cgoバイナリのPT_TLS生成を有効にし、OpenBSD 6.0以降を必要とします。Go 1.9はOpenBSD 5.9をサポートしなくなりました。
既知の問題
FreeBSDでいくつかの不安定性が知られていますが、理解されていません。これらはまれにプログラムのクラッシュを引き起こす可能性があります。issue 15658 を参照してください。このFreeBSD固有の問題の解決に役立つ情報をお待ちしています。Goは、NetBSDカーネルのクラッシュのため、Go 1.9の開発サイクル中にNetBSDビルダーの実行を停止しました。Go 1.9がリリースされると、NetBSD 7.1.1が修正を伴ってリリースされます。しかし、現時点では、テストスイートを通過するNetBSDビルダーはありません。さまざまなNetBSDの問題 の調査にご協力いただければ幸いです。
ツール
並列コンパイル
Goコンパイラは、パッケージの関数を並列にコンパイルすることをサポートし、複数のコアを活用します。これは、goコマンドの既存の別々のパッケージの並列コンパイルのサポートに加えて行われます。並列コンパイルはデフォルトで有効になっていますが、環境変数GO19CONCURRENTCOMPILATION
を0に設定することで無効にできます。
./…によるベンダーマッチング
多くの要望に応じて、./…は、go testなどのパッケージ名を受け入れるツールで、ベンダーディレクトリ内のパッケージを一致させなくなりました。ベンダーディレクトリを一致させるには、./vendor/…と書きます。
移動されたGOROOT
goツール
は、呼び出されたパスを使用してGoインストールツリーのルートを見つけようとします。これは、Goのインストール全体が新しい場所に移動された場合でも、goツールが通常通り動作することを意味します。これは環境でGOROOT
を設定することで上書きできますが、これは通常の状況では行うべきではありません。これは、runtime.GOROOT
関数の結果には影響しません。この関数は引き続き元のインストール場所を報告します。これは後のリリースで修正される可能性があります。
コンパイラツールチェーン
複素数の除算は、今やC99互換です。これは常にgccgoでのケースであり、gcツールチェーンでも修正されました。リンカは、Windows上のcgo実行ファイルのためにDWARF情報を生成するようになりました。コンパイラは、-N -l
フラグが提供された場合、生成されたDWARFに字句スコープを含めるようになり、デバッガがスコープ外の変数を隠すことができます。.debug_info
セクションは現在DWARFバージョン4です。GOARM
とGO386
の値は、goツールの依存関係キャッシングで使用されるコンパイル済みパッケージのビルドIDに影響を与えるようになりました。
アセンブラ
4オペランドのARM MULA
命令は、加算レジスタを第3引数として、結果レジスタを第4および最後の引数として正しくアセンブルされるようになりました。以前のリリースでは、2つの意味が逆になっていました。第4引数が暗黙的に第3引数と同じである3オペランド形式は影響を受けません。4オペランドのMULA
命令を使用するコードは更新が必要ですが、この形式は非常にまれにしか使用されないと考えています。MULAWT
とMULAWB
はすでにすべての形式で正しい順序を使用しており、変更されていません。アセンブラは現在、ADDSUBPS/PD
をサポートしており、2つの欠けていたx86 SSE3命令を完成させています。
ドキュメント
引数の長いリストは現在切り捨てられます。これにより、一部の生成されたコードでのgo doc
の可読性が向上します。構造体フィールドのドキュメントの表示がサポートされるようになりました。たとえば、go doc http.Client.Jar
です。
環境
新しいgo env -json
フラグは、デフォルトのOS固有の出力形式の代わりにJSON出力を有効にします。
テスト
go test
コマンドは、新しい-list
フラグを受け入れ、正規表現を引数として取り、実行せずに一致するテスト、ベンチマーク、または例の名前を標準出力に出力します。
Pprof
runtime/pprof
パッケージによって生成されたプロファイルには、シンボル情報が含まれるようになり、プロファイルを生成したバイナリなしでgo tool pprof
で表示できます。go tool pprof
コマンドは、環境で定義されたHTTPプロキシ情報を使用し、http.ProxyFromEnvironment
を使用します。
Vet
vetコマンド
は、goツール
により統合され、go vet
はすべての標準ビルドフラグをサポートするようになり、vetの独自のフラグはgo vet
およびgo tool vet
から利用可能になりました。
Gccgo
Goの半年ごとのリリーススケジュールとGCCの年次リリーススケジュールの整合性により、GCCリリース7にはGo 1.8.3バージョンのgccgoが含まれています。次のリリースであるGCC 8には、Go 1.10バージョンのgccgoが含まれると予想しています。
ランタイム
インラインフレームを含むコールスタック
runtime.Callers
のユーザーは、結果のPCスライスを直接検査するのではなく、コールスタックの完全なビューを取得するためにruntime.CallersFrames
を使用するか、単一の呼び出し元に関する情報を取得するためにruntime.Caller
を使用するべきです。これは、PCスライスの個々の要素がインラインフレームやコールスタックの他のニュアンスを考慮できないためです。具体的には、PCスライスを直接反復処理し、各PCを個別に解決するためにruntime.FuncForPC
などの関数を使用するコードは、インラインフレームを見逃します。スタックの完全なビューを取得するには、そのようなコードは代わりにCallersFrames
を使用する必要があります。同様に、Callers
によって返される長さがコールの深さを示すものではないと仮定すべきではありません。代わりに、CallersFrames
によって返されるフレームの数を数えるべきです。特定の深さで単一の呼び出し元を照会するコードは、長さ1のスライスをCallers
に渡すのではなく、Caller
を使用するべきです。runtime.CallersFrames
はGo 1.7以降利用可能であるため、Go 1.9にアップグレードする前にコードを更新できます。
パフォーマンス
いつものように、変更は非常に一般的で多様であるため、パフォーマンスに関する正確な声明を出すのは難しいです。ほとんどのプログラムは、ガベージコレクタの速度向上、生成されたコードの改善、およびコアライブラリの最適化により、少し速く実行されるはずです。
ガベージコレクタ
以前はストップ・ザ・ワールドガベージコレクションをトリガーしていたライブラリ関数が、現在は並行ガベージコレクションをトリガーします。具体的には、runtime.GC
、debug.SetGCPercent
、およびdebug.FreeOSMemory
は、現在並行ガベージコレクションをトリガーし、ガベージコレクションが完了するまで呼び出し元のゴルーチンのみをブロックします。debug.SetGCPercent
関数は、新しいGOGC
値のために即座に必要な場合にのみガベージコレクションをトリガーします。これにより、GOGC
をオンザフライで調整することが可能になります。大きなオブジェクトの割り当てパフォーマンスは、多くの大きなオブジェクトを含む大きな(>50GB)ヒープを使用するアプリケーションで大幅に改善されました。runtime.ReadMemStats
関数は、非常に大きなヒープでも100µs未満で実行されるようになりました。
標準ライブラリ
透明な単調時間サポート
time パッケージは、各Time 値で単調時間を透過的に追跡するようになり、2つのTime値間の期間を計算することが、壁時計の調整がある場合でも安全な操作になります。パッケージドキュメント と設計文書 を参照してください。
新しいビット操作パッケージ
Go 1.9には、新しいパッケージmath/bits が含まれており、ビット操作の最適化された実装が提供されています。ほとんどのアーキテクチャでは、このパッケージの関数はコンパイラによって認識され、追加のパフォーマンスのためにイントリンシックとして扱われます。
テストヘルパー関数
新しい(*T).Helper および(*B).Helper メソッドは、呼び出し元の関数をテストヘルパー関数としてマークします。ファイルと行情報を印刷する際に、その関数はスキップされます。これにより、テストヘルパー関数を記述しながら、ユーザーにとって有用な行番号を持つことができます。
並行マップ
sync パッケージの新しいMap 型は、償却定数時間のロード、ストア、および削除を持つ並行マップです。複数のゴルーチンが同時にMapのメソッドを呼び出すことが安全です。
プロファイララベル
runtime/pprofパッケージ は、pprofプロファイラレコードにラベルを追加することをサポートするようになりました。ラベルは、pprofコマンド でプロファイルを確認する際に、異なるコンテキストで同じ関数の呼び出しを区別するために使用されるキーと値のマップを形成します。pprofパッケージの新しいDo関数 は、提供されたラベルに関連付けられたコードを実行します。パッケージ内の他の新しい関数は、ラベルを操作するのに役立ちます。
ライブラリの小さな変更
いつものように、Go 1の互換性の約束 を念頭に置いて、ライブラリにさまざまな小さな変更と更新が行われています。
archive/zip
ZIP Writer は、適切な場合にFileHeader.Flags にUTF-8ビットを設定するようになりました。
crypto/rand
Linuxでは、GoはGRND_NONBLOCKフラグなしでgetrandomシステムコールを呼び出すようになり、カーネルに十分なランダム性があるまでブロックします。getrandomシステムコールが存在しないカーネルでは、Goは/dev/urandomから読み続けます。
crypto/x509
Unixシステムでは、環境変数SSL_CERT_FILE
とSSL_CERT_DIR
を使用して、SSL証明書ファイルとSSL証明書ファイルディレクトリのシステムデフォルトの場所を上書きできるようになりました。FreeBSDファイル/usr/local/etc/ssl/cert.pem
が証明書検索パスに含まれるようになりました。パッケージは、名前制約で除外されたドメインをサポートするようになりました。このような制約を強制することに加えて、CreateCertificate
は、提供されたテンプレート証明書に新しいフィールドExcludedDNSDomains
が入力されている場合、除外された名前制約を持つ証明書を作成します。DNS名を含まないものを含むSAN拡張が証明書に存在する場合、Subject
からの共通名は無視されます。以前のリリースでは、コードは証明書にDNS名のSANが存在するかどうかのみをテストしていました。
database/sql
パッケージは、Tx.Stmt
で利用可能な場合、キャッシュされたStmt
を使用するようになりました。これにより、Tx.Stmt
が呼び出されるたびにステートメントが再準備されるのを防ぎます。パッケージは、driver.NamedValueChecker
を実装することで、ドライバが独自の引数チェッカーを実装することを許可するようになりました。これにより、ドライバがOUTPUT
およびINOUT
パラメータタイプをサポートすることも可能になります。ドライバがサポートする場合、Out
を使用して出力パラメータを返すべきです。Rows.Scan
は、ユーザー定義の文字列型をスキャンできるようになりました。以前は、パッケージはtype Int int64
のような数値型へのスキャンをサポートしていましたが、type String string
のような文字列型へのスキャンもサポートするようになりました。新しいDB.Conn
メソッドは、接続プールからデータベースへの排他的な接続を表す新しいConn
型を返します。Conn
で実行されるすべてのクエリは、Conn.Close
が呼び出されて接続が接続プールに戻されるまで、同じ基礎となる接続を使用します。
encoding/asn1
新しいNullBytes とNullRawValue は、ASN.1 NULL型を表します。
encoding/base32
新しいEncoding.WithPadding メソッドは、カスタムパディング文字とパディングの無効化をサポートします。
encoding/csv
新しいフィールドReader.ReuseRecord は、Read の呼び出しが、前回の呼び出しで返されたスライスのバック配列を共有するスライスを返すかどうかを制御し、パフォーマンスを向上させます。
fmt
シャープフラグ('#'
)は、浮動小数点数と複素数を印刷する際にサポートされるようになりました。これは、%e
, %E
, %f
, %F
, %g
, %G
に対して常に小数点を印刷し、%g
と%G
に対して末尾のゼロを削除しません。
hash/fnv
パッケージには、New128 およびNew128a を使用した128ビットFNV-1およびFNV-1aハッシュサポートが含まれるようになりました。
html/template
パッケージは、パイプラインで事前定義されたエスケーパー(“html”、“urlquery”、“js”のいずれか)が見つかり、それが自動エスケーパーが独自に決定したものと一致しない場合にエラーを報告するようになりました。これにより、特定のセキュリティまたは正確性の問題を回避できます。これらのエスケーパーの使用は、常にノーオペレーションまたはエラーのいずれかです。(ノーオペレーションの場合は、text/template からの移行を容易にします。)
image
Rectangle.Intersect メソッドは、隣接しているが重ならない矩形に対して呼び出された場合、ゼロの矩形を返すようになりました。以前のリリースでは、空であるがゼロでない矩形を誤って返していました。
image/color
YCbCrからRGBAへの変換式が調整され、丸め調整が完全な[0, 0xffff]
RGBA範囲をカバーするようになりました。
image/png
新しいEncoder.BufferPool
フィールドは、PNG画像をエンコードする際にエンコーダが一時的なEncoderBuffer
バッファを取得するために使用するEncoderBufferPool
を指定することを可能にします。BufferPool
の使用により、複数の画像をエンコードする際のメモリアロケーションの数が減少します。パッケージは、透明な8ビットグレースケール(“Gray8”)画像のデコードをサポートするようになりました。
math/big
新しいIsInt64
およびIsUint64
メソッドは、Int
がint64
またはuint64
値として表現できるかどうかを報告します。
mime/multipart
新しいFileHeader.Size フィールドは、マルチパートメッセージ内のファイルのサイズを示します。
net
新しいResolver.StrictErrors
は、Goの組み込みDNSリゾルバが、A+AAAAアドレスルックアップのような複数のサブクエリで構成されるクエリ中の一時的なエラーをどのように処理するかを制御します。新しいResolver.Dial
は、リゾルバがカスタムダイアル関数を使用することを可能にします。JoinHostPort
は、ホストにコロンが含まれている場合にのみアドレスを角括弧で囲むようになりました。以前のリリースでは、パーセント('%'
)記号が含まれている場合にもアドレスを角括弧で囲んでいました。新しいメソッドTCPConn.SyscallConn
、IPConn.SyscallConn
、UDPConn.SyscallConn
、およびUnixConn.SyscallConn
は、接続の基礎となるファイルディスクリプタへのアクセスを提供します。(*TCPListener).String()から取得したアドレスでDial
を呼び出すことが安全になりました。以前は、IPv6スタックが半分構成されたマシンで失敗していました。
net/http
Cookie.String メソッドは、CookieおよびSet-Cookieヘッダーに使用され、値にスペースまたはカンマが含まれている場合に値を二重引用符で囲むようになりました。
サーバーの変更:
ServeMux は、ハンドラを一致させる際にホストヘッダーのポートを無視するようになりました。ホストはCONNECTリクエストに対して変更されずに一致します。
新しいServer.ServeTLS メソッドは、TLSサポートを追加してServer.Serve をラップします。
Server.WriteTimeout は、HTTP/2接続に適用され、ストリームごとに強制されるようになりました。
HTTP/2は、デフォルトで優先度書き込みスケジューラを使用するようになりました。フレームは、RFC 7540セクション5.3 で説明されているように、HTTP/2の優先度に従ってスケジュールされます。
StripPrefix
によって返されるHTTPハンドラは、元の*http.Request
の修正されたクローンを使用して提供されたハンドラを呼び出すようになりました。*http.Requestをキーとするマップにリクエストごとの状態を格納するコードは、Request.Context
、Request.WithContext
、およびcontext.WithValue
を代わりに使用するべきです。
LocalAddrContextKey は、リスナーによって使用されるインターフェースアドレスではなく、接続の実際のネットワークアドレスを含むようになりました。
クライアントとトランスポートの変更:
Transport
は、Transport.Proxy
によって返されるURLのスキームがsocks5
である場合、SOCKS5プロキシ経由でリクエストを行うことをサポートするようになりました。
net/http/fcgi
新しいProcessEnv
関数は、HTTPリクエストに関連付けられたFastCGI環境変数を返します。これには、REMOTE_USER
のような適切なhttp.Request
フィールドがありません。
net/http/httptest
新しいServer.Client メソッドは、テストサーバーへのリクエストを行うために構成されたHTTPクライアントを返します。新しいServer.Certificate メソッドは、テストサーバーのTLS証明書を返します(存在する場合)。
net/http/httputil
ReverseProxy は、初期応答ヘッダーで宣言されていないものを含むすべてのHTTP/2応答トレーラーをプロキシするようになりました。このような宣言されていないトレーラーは、gRPCプロトコルで使用されます。
os
osパッケージは、ファイルI/Oのために内部ランタイムポーラーを使用するようになりました。これにより、パイプでの読み取り/書き込み操作に必要なスレッドの数が減少し、1つのゴルーチンがファイルを閉じている間に別のゴルーチンがファイルをI/Oに使用しているときの競合状態が排除されます。Windowsでは、Args はshell32.dllなしで入力されるようになり、プロセスの起動時間が1〜7ミリ秒短縮されます。
os/exec
os/execパッケージは、重複した環境変数を持つ子プロセスが作成されるのを防ぐようになりました。Cmd.Env に重複する環境キーが含まれている場合、各重複キーの最後の値のみが使用されます。
os/user
Lookup およびLookupId は、CGO_ENABLED=0のときにUnixシステムで/etc/passwdファイルを読み取ることで動作するようになりました。LookupGroup およびLookupGroupId は、CGO_ENABLED=0のときにUnixシステムで/etc/groupファイルを読み取ることで動作するようになりました。
reflect
新しいMakeMapWithSize 関数は、容量のヒントを持つマップを作成します。
runtime
ランタイムによって生成され、プロファイルに記録されたトレースバックは、インライン化が存在する場合でも正確です。トレースバックをプログラムで取得するには、アプリケーションはruntime.CallersFrames を使用するべきであり、runtime.Callers の結果を直接反復処理するべきではありません。Windowsでは、Goはプログラムがアイドル状態のときにシステムタイマーを高解像度で実行することを強制しなくなりました。これにより、Goプログラムのバッテリー寿命への影響が軽減されるはずです。FreeBSDでは、GOMAXPROCSおよびruntime.NumCPU は、プロセスのCPUマスクに基づいており、CPUの総数ではありません。ランタイムはAndroid Oの予備サポートを持っています。
runtime/debug
SetGCPercent を負の値で呼び出しても、即時のガベージコレクションは実行されなくなりました。
runtime/trace
実行トレースは、アプリケーションのゴルーチンがガベージコレクションを支援することを強制されるときに、マークアシストイベントを表示するようになりました。これは、アプリケーションがあまりにも速く割り当てを行っているためです。「スイープ」イベントは、個々のスパンがスイープされるたびに記録するのではなく、割り当てのための空きスペースを見つけるプロセス全体を含むようになりました。これにより、割り当てが多いプログラムのトレース時の割り当て待ち時間が短縮されます。スイープイベントは、スイープされたバイト数と回収されたバイト数を示します。
sync
Mutex は、より公平になりました。
syscall
新しいフィールドCredential.NoSetGroups は、Unixシステムが新しいプロセスを開始するときに補助グループを設定するためにsetgroupsシステムコールを行うかどうかを制御します。新しいフィールドSysProcAttr.AmbientCaps は、新しいプロセスを作成するときにLinux 4.3+でアンビエントキャパビリティを設定することを可能にします。64ビットx86 Linuxでは、CLONE_VFORKおよびCLONE_VMの使用によりプロセス作成待ち時間が最適化されました。新しいConn インターフェースは、net パッケージ内のいくつかの型を記述し、新しいRawConn インターフェースを使用して基礎となるファイルディスクリプタへのアクセスを提供します。
testing/quick
パッケージは、int64およびuint64の乱数を生成する際に、完全な範囲で値を選択するようになりました。以前のリリースでは、生成された値は常に[-262, 262)
範囲に制限されていました。以前のリリースでは、nil
のConfig.Rand
値を使用すると、固定された決定論的な乱数生成器が使用されていました。現在は、現在の時刻でシードされた乱数生成器を使用します。以前の動作を得るには、Config.Rand
をrand.New(rand.NewSource(0))
に設定します。
text/template
Go 1.8の変更により、テンプレートの順序に依存する結果が発生するようになった空のブロックの処理が修正され、以前のGo 1.7の動作が復元されました。
time
新しいメソッドDuration.Round
およびDuration.Truncate
は、指定された期間の倍数に期間を丸めたり切り捨てたりする処理を行います。時間の取得とスリープは、Wineの下で正しく動作するようになりました。Time
値に単調クロックの読み取りがある場合、その文字列表現(String
によって返される)は、最終フィールド"m=±value"
を含むようになり、value
は秒数としてフォーマットされた単調クロックの読み取りです。含まれているtzdata
タイムゾーンデータベースはバージョン2017bに更新されました。これは、システムにすでにデータベースが利用可能でない場合にのみ使用されます。