この記事は https://golang.org/doc/go1.14 を日本語訳したものです. 前のバージョンはこちら: Go 1.13 リリースノート 日本語訳. 次のバージョンはこちら: Go 1.15 リリースノート 日本語訳.
Go 1.14 の紹介
最新の Go リリース、バージョン 1.14 は、Go 1.13 から6か月後に届きます. その変更点のほとんどは、ツールチェーン、ランタイム、およびライブラリの実装になります. いつものように、このリリースは Go 1 の互換性の約束を守っています. 私たちは、ほとんどすべての Go プログラムが以前と同じようにコンパイルし実行し続けれると予想しています.
go コマンドのモジュールサポートを本番で使用する準備ができましたので、すべてのユーザが依存性管理のために Go モジュールに移行することをおすすめします.
もし Go のツールチェーンの問題のせいで移行できない場合には、その問題が 未解決の問題 として起票されていることを確認してください. (もし問題が Go1.15 マイルストーンにない場合には、適切に優先順位付けできるよう、移行を妨げている理由をお知らせください.)
言語への変更
オーバーラップするインターフェイスの提案 により、Go 1.14 ではオーバーラップするメソッドセットを持つインターフェイスの埋め込みが可能になりました. 埋め込みインターフェイスのメソッドは、(埋め込み)インターフェイスにすでに存在するメソッドと同じ名前と同一のシグネチャを持つことができます. これにより、ダイアモンド形状の埋め込みグラフで典型的に発生する(しかしそれだけに限らない)問題が解決されます. インタフェースで明示的に宣言されたメソッドは、今までと同様に一意でなければなりません.
ポート
Darwin
Go 1.14 は macOS 10.11 El Capitan 上で走る最後のリリースです. Go 1.15 は macOS 10.12 Sierra 以降を必要とする予定です.
Go 1.14 は maxOS (darwin/386 ポート) 上で32ビットバイナリをサポートする最後のリリースです. 32ビットバイナリは macOS 10.15 (Catalina) 以降、macOS ではサポートされなくなりました. Go は64ビットの darwin/amd64 ポートのサポートを継続します.
Go 1.14 はおそらく iOS, iPadOS, watchOS, tvOS (darwin/arm ポート)上で32ビットバイナリをサポートする最後のGoリリースになります. Go は64ビットの darwin/arm64 ポートのサポートを継続します.
Windows
Windows 上の Go バイナリは DEP (Data Execution Prevention) が有効になりました.
Windows で、os.OpenFile に os.O_CREATE フラグや、 syscall.Open に syscall.O_CREAT フラグを指定したファイルの作成は、パーミション引数にビット 0o200 (所有者の書き込み許可)を設定しなかった場合、ファイルが読み取り専用で作成されるようになりました. これにより Windows での挙動がより Unix システム上での挙動に似たものになりました.
WebAssembly
js.Value オブジェクト経由で Go から参照した JavaScript の値がガベージコレクトされるようになりました.
js.Value の値は == 演算子で比較することができなくなり、代わりに Equal メソッドを使って比較されなくてはなりません.
js.Value は IsUndefined、IsNull、IsNaN メソッドを持つようになりました.
RISC-V
Go 1.14 は Linux (GOOS=linux, GOARCH=riscv64) 上の 64ビット RISC-V の実験的サポートを含んでいる. パフォーマンス、アセンブリ構文の安定性、場合によっては正確性でさえ、作業中であることに注意してください.
FreeBSD
Go は FreeBDS 12.0 以降で64ビット ARM アーキテクチャ(freebsd/arm64 ポート)をサポートしました.
Native Client (NaCl)
Go 1.13 のリリースノートでアナウンス した通り、Go 1.14 は Native Client プラットフォーム (GOOS=nacl) のサポートを破棄します.
Illumos
ランタイムは、runtime.NumCPU と GOMAXPROCS のデフォルト値のためのゾーン CPU の上限(zone.cpu-cap リソースコントロール)を考慮するようになりました.
ツール
Go コマンド
ベンダリング
メインモジュールにトップレベルの vendor ディレクトリが含まれており、その go.mod ファイルで go 1.14 以上が指定されている場合、go コマンドは、フラグを受け入れる操作に対してデフォルトで -mod=vendor が設定されるようになりました. このフラグの新しい値 -mod=mod を指定すると、go コマンドは(vendor ディレクトリが存在しない時のように)代わりにモジュールキャッシュからモジュールをロードします.
(明示的であれデフォルトであれ) -mod=vendor が設定されている場合、go コマンドはメインモジュールの vendor/modules.txt ファイルと go.mod ファイルの整合性を確認するようになりました.
go list -m は、vendor ディレクトリの中のパッケージに提供されない推移的な依存関係を暗黙的に省略しなくなりました. -mod=vendor が設定され、vendor/modules.txt に記述されていないモジュールに対して情報が要求された場合、明示的に失敗するようになります.
フラグ
go get コマンドは -mod フラグを受け付けなくなりました. 以前はフラグの設定が無視されたか、ビルドの失敗を引き起こしていました.
go.mod ファイルが読み取り専用で、トップレベルのベンダーディレクトリが存在しない場合、-mod=readonly がデフォルトで設定されるようになりました.
-modcacherw は、新しく作成されたディレクトリを読み取り専用にするのではなく、デフォルトのアクセス権のままでモジュールキャッシュに残すように go コマンドに指示する新しいフラグです. このフラグを使用すると、テストやその他のツールによって、モジュールの検証済みチェックサムに含まれていないファイルが誤って追加される可能性が高くなります. ただし、(go clean -modcache の代わりに) rm -rf を使用してモジュールキャッシュを削除できます.
-modfile=file は新しいフラグで、go コマンドにモジュールのルートディレクトリの中の go.mod ファイルの代わりに代替のファイルを読み込む(可能であれば書き込みも)ように指示します. モジュールのルートディレクトリを特定するために、go.mod という名前のファイルはまだ存在している必要がありますが、アクセスはされません. -modfile を指定すると、代替の go.sum ファイルも使用されます. そのパスは .mod 拡張子を削除して .sum を追加することにより、-modfile フラグから導出されます.
環境変数
GOINSECURE は新しい環境変数で、go コマンドが特定のモジュールをオリジンから直接取得するときに、HTTPS 接続を必要としないよう、証明書の検証をスキップするよう指示します. 既存の GOPRIVATE のように、GOINSECURE の値は、glob パターンのカンマ区切りのリストです.
モジュール外のコマンド
(GO111MODULE=on を設定することによって)モジュール認識モードが明示的に有効な場合、go.mod ファイルが存在しない場合、ほとんどのモジュールコマンドの機能が制限されます. 例えば、go build、go run、およびその他のビルドコマンドは、標準ライブラリ内のパッケージと、コマンド行で .go ファイルとして指定されたパッケージだけをビルドできます.
以前は、go コマンドはそれぞれのパッケージパスをモジュールの最新バージョンに解決しますが、モジュールのパスやバージョンは記録しませんでした. その結果、遅くて、再現できないビルドとなりました.
go get は以前と同じように動作しますし、バージョンを明示した go mod download と go list -m も同様です.
+incompatible バージョン
モジュールの最新バージョンに go.mod ファイルが含まれている場合、go get は、そのバージョンが明示的に要求されているか、すでに必要とされていない限り、そのモジュールの互換性のないメジャーバージョンにはアップグレードしません. go list もバージョン管理から直接取得する際にそのようなモジュールの互換性のないメジャーバージョンを省略しますが、プロキシから報告された場合にはそれらを含めるかもしれません.
go.mod ファイルメンテナンス
go mod tidy 以外の go コマンドは、メインモジュールの他の(推移的な)依存関係によってすでに暗示されている間接的な依存関係のバージョンを指定する require ディレクティブを削除しなくなりました.
go mod tidy 以外の go コマンドは、変更が表面的なものだけならば go.mod ファイルを編集しなくなります.
-mod=readonly を設定すると、go ディレクティブがなかったり、誤った // indirect コメントを原因として失敗することがなくなります.
モジュールダウンロード
go コマンドはモジュールモードで Subversion レポジトリをサポートしました.
go コマンドには、モジュールプロキシや他の HTTP サーバからのプレインテキストのエラーメッセージのスニペットが含まれるようになりました. エラーメッセージは、有効な UTF-8 で、グラフィック文字とスペースだけで構成されている場合にのみ表示されます.
テスト
go test -v はすべてのテストの終了時ではなく、発生時に t.Log 出力をストリームするようになりました.
ランタイム
このリリースでは、defer された関数を直接呼び出す場合と比較して、大半の defer 使用のパフォーマンスがほぼオーバヘッド無しに改善しました. 結果として、defer はオーバーヘッドを気にすることなく、パフォーマンスがクリティカルなコードで使用できるようになりました.
Goroutine が非同期でプリエンプティブ可能になりました. 結果として、関数呼び出しのないループでスケジューラがデッドロックしたり、ガベージコレクションが大幅に遅延する可能性がなくなりました. これは windows/arm、darwin/arm、js/wasm、plan9/* を除く全てのプラットフォームでサポートされています.
プリエンプションの実装の結果として、Linux や macOS システムを含む Unix システムでは、Go 1.14 でビルドされたプログラムは以前のリリースでビルドされたプログラムよりも多くのシグナルを受け取ります. このことは、syscall や golang.org/x/sys/unix のようなパッケージを使うプログラムで遅いシステムコールが EINTR で失敗するのをより目撃するようになることを意味します. それらのプログラムは、ループでシステムコールに再びトライする可能性が高いと思いますが、何らかの方法でエラーを処理する必要があります. この件についての情報が知りたければ、Linux システムのための man 7 signal や他のシステムのための同様のドキュメントを見てください.
ページアロケータは GOMAXPROCS が高い値のときに、より効率的で大幅にロック競合が少なくなりました. 並列かつ高い頻度での大規模な割当では、より低いレイテンシと高いスループットが顕著になります.
time.After、time.Tick、net.Conn.SetDeadline 等で使われる内部タイマーは、ロック競合とコンテキストスイッチが少なくなり、より効率的になりました. これはユーザの目に見える変更のないパフォーマンスの改善です.
コンパイラ
このリリースは、Go コードが unsafe.Pointer 安全ルールに従っているかを動的にチェックするための測定を追加する、コンパイル時のオプションとして -d=checkptr が追加されました. このオプションは -race または -msan フラグでデフォルトで有効になり(Windows を除く)、-gcflags=all=-d=checkptr=0 で無効にすることができます. 特に -d=checkptr は以下をチェックします:
-
unsafe.Pointerを*Tに変換するときは、結果のポインタがTに適切に整合する必要があります. - ポインタ演算の結果が Go ヒープオブジェクトを指している場合、
unsafe.Pointer型のオペランドの一つが同じオブジェクトを指している必要があります.
-d=checkptr を使うと、標準ライブラリで誤ったアラートが発生するので、現在のところは Windows での使用が推奨されていません.
コンパイラは -json フラグによって、インライニング、エスケープ解析、境界チェック削除、nil チェック削除を含む、主要な最適化の機械可読ログを出力できるようになりました.
詳細なエスケープ解析診断 (-m=2) が再び動作するようになりました. これは、以前のリリースの新しいエスケープ解析の実装で破棄されていました.
macOS バイナリでの Go のすべてのシンボルは、プラットフォームの規約に従って、アンダースコアで始まるようになりました.
このリリースには、ファジングのための、コンパイラがカバレッジのために挿入する測定の実験的サポートが含まれています. 詳細については 課題 14565を参照してください. この API は将来のリリースで変更される可能性があります.
境界チェックの削除でスライス作成からの情報が使用されるようになり、int より小さい型のインデックスのチェックを削除できるようになりました.
コアライブラリ
新しいバイトシーケンスのハッシュパッケージ
Go 1.14 はバイトシーケンスのハッシュ関数を提供する新しいパッケージ hash/maphash を含んでいます. これらのハッシュ関数は、任意の文字列またはバイトシーケンスを正の64ビット整数の均一な分布にマップする必要があるハッシュテーブルまたはその他のデータ構造を実装するために使われることを意図しています.
このハッシュ関数は衝突耐性がありますが、暗号学的に安全ではありません.
与えられたバイト列のハッシュ値は、1つのプロセス内では一貫していますが、プロセスが異なれば異なります.
ライブラリへの小さな変更
いつものように、Go 1の 互換性の約束を念頭に置いて行われた、ライブラリに対するさまざまな小さな変更と更新があります.
crypto/tls
SSL バージョン 3.0 (SSLv3) のサポートは削除されました. SSLv3 は、TLS 以前の危殆化した暗号プロトコルであることに注意されたい.
TLS 1.3 は GODEBUG 環境変数で無効にすることができなくなりました. TLS のバージョンを設定するには Config.MaxVersion フィールドを使ってください.
Config.Certificates フィールドを通して複数の証明書チェーンを提供する場合、ピアと互換性のある最初の証明書チェーンが自動的に選択されるようになりました. これにより、たとえば ECDSA と RSA 証明書を提供し、パッケージが自動的に最適なものを選択できるようになります. Certificate.Leaf フィールドが設定されていない場合、この選択のパフォーマンスは低下することにご注意ください.
新しい CipherSuites 関数と InsecureCipherSuites 関数は、現在実装されている暗号スイートのリストを返します. 新しい [CipherSuiteName] 関数は、暗号スイート ID の名前を返します.
新しい (*ClientHelloInfo).SupportsCertificate と (*CertificateRequestInfo).SupportsCertificate メソッドは、ピアが特定の証明書をサポートしているかどうかを公開します.
tls パッケージは Next Protocol Negotiation (NPN) 拡張をサポートしなくなり、現在は ALPN のみをサポートしています. 以前のリリースでは両方をサポートしていました. API に変更はなく、アプリケーションは以前と同じように機能するはずです. 他のクライアントとサーバのほとんどは、標準化された ALPN を支持していて、すでに NPN サポートを削除しています.
TLS 1.2 ハンドシェイクでサポートされる場合、RSA-PSS 署名が使用されるようになりました. これはほとんどのアプリケーションには影響しませんが、RSA-PSS 署名をサポートしていないカスタム Certificate.PrivateKey 実装は、それらを無効にするために新しい Certificate.SupportedSignatureAlgorithms フィールドを使用する必要があります.
Config.GetConfigForClient が設定されている場合、Config.Certificates と Config.GetCertificate の両方を nil にできるようになりました. コールバックが証明書もエラーも返さない場合、unrecognized_name が送信されます.
新しい CertificateRequestInfo.Version フィールドは、クライアント証明書コールバックに TLS バージョンを提供します.
以前は TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 と TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 と呼ばれていた暗号スイートの最終的な名前として、新しい TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 定数と TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 定数を使います.
crypto/x509
Certificate.CreateCRL は Ed25519 の発行者をサポートしました.
debug/dwarf
debug/dwarf パッケージは、DWARF バージョン 5 の読み込みをサポートしました.
新しいメソッド (*Data).AddSection は、入力ファイルから DWARF Data への任意の新しい DWARF セクションの追加をサポートします.
新しいメソッド (*Reader).ByteOrder は、現在のコンパイル単位のバイトオーダーを返します. これは、場所の記述など、ネイティブの順序でエンコードされた属性を解釈するために使用することができます.
新しいメソッド (*LineReader).Files は、ラインリーダーからファイル名テーブルを返します. これは、AttrDeclFile などのDWARF 属性の値を解釈するために使用することができます.
encoding/asn1
Unmarshal は、新しい TagBMPString 定数で表される、ASN.1 文字列型の BMPString をサポートするようになりました.
encoding/json
Decoder 型は、現在のデコーダ位置の入力ストリームのバイトオフセットを返す新しいメソッド InputOffset をサポートします.
Compactは、文書化されていない、U+2028 と U+2029 文字のエスケープをしなくなりました. 正しいエスケープについては、HTMLEscape を参照してください.
ドキュメントに記載されている挙動により厳密に従うために、Number が無効な数値を受け入れなくなりました. プログラムが空文字列のような無効な数値を受け入れる必要がある場合は、型を Unmarshaler でラップすることを検討してください.
go/build
Context 型はビルドの作業ディレクトリを設定するために使用できる新しいフィールド Dir を持っています. デフォルトは実行中のプロセスのカレントディレクトリです. モジュールモードではメインモジュールの位置を特定するのに使用します.
go/doc
新しい関数 NewFromFiles は、*ast.Fileのリストからパッケージドキュメントを計算し、適切なパッケージ要素に例を関連付けます. 新しい情報は Package、Type、Func 型の新しい Examples フィールドと、Example 型の新しい Suffix フィールドにあります.
io/ioutil
TempDir は、予測可能なプレフィックスとサフィックスを名前に持つディレクトリを作成できるようになりました. TempFile と同様に、パターンに '*' が含まれている場合は、最後の '*' がランダムな文字列に置き換えられます.
log
新しい Lmsgprefix フラグを使用すると、オプションの出力プレフィックスを行の先頭ではなく、ログメッセージの直前に出力するようにロギング関数に指示することができます.
math
新しい FMA 関数は、x*y 計算の中間丸めを行わずに、x*y+z を浮動小数点で計算します. いくつかのアーキテクチャでは、専用のハードウェア命令を使用してこの計算を実装し、更なるパフォーマンスを得ています.
math/big
GCD 関数は入力の a と b に0または負の数を受け付けるようになりました.
math/bits
新しい関数 Rem、Rem32、Rem64 は商がオーバーフローした場合でも剰余の計算をサポートします.
mime
.js ファイルと .mjs ファイルのデフォルトタイプは application/javascript ではなく text/javascript になりました. これは、application/javascript を廃止されたものとして扱うIETF ドラフトに従っています.
mime/multipart
Reader の新しいメソッド NextRawPart は quoted-printable のデータを透過的にデコードすることなしに、次の MIME パートを取得することをサポートしています.
net/http
Header の新しいメソッド Values は正規化されたキーに関連付けられたすべての値を取得することに使えます.
Transport の新しいフィールド DialTLSContext は、プロキシを使わない HTTPS 要求のための TLS 接続を作成するためのオプションのダイヤル関数を指定することに使えます. この新しいフィールドは、いまや廃止となった DialTLS の代わりに使うことができます. DialTLS は引き続き動作しますが、新しいコードでは不要になったらすぐにトランスポートがダイヤルをキャンセルできる DialTLSContext を使うべきです.
Windows 上で ServeFile は 2GB を超えるファイルを正しく処理するようになりました.
net/http/httptest
Server の新しいフィールド EnableHTTP2 はテストサーバで HTTP/2 を有効にすることをサポートします.
net/textproto
MIMEHeader の新しいメソッド Values は正規化されたキーに関連付けられたすべての値を取得することに使えます.
net/url
URL の解析に失敗(例えば Parse や ParseRequestURI によって)した時、結果の Error のメッセージは解析できなかった URL を引用するようになりました. これにより、構造がより明確になり、他の解析エラーとの一貫性がもたらされます.
os/signal
Windows では、Control-C と Control-Break が syscall.SIGINT を生成するように、CTRL_CLOSE_EVENT、CTRL_LOGOFF_EVENT、CTRL_SHUTDOWN_EVENT イベントは syscall.SIGTERM シグナルを生成するようになりました.
plugin
plugin パッケージは freebsd/amd64 をサポートしました.
reflect
StructOf は、StructField 要素に PkgPath フィールドを設定することによって、エクスポートされていないフィールドを持つ構造体の型の生成をサポートしました.
runtime
再帰的な panic、recover によって runtime.Goexit が中止することはなくなりました.
macOS では、SIGPIPE は Go ランタイムが初期化される前にインストールされたシグナルハンドラに転送されなくなりました. これが必要なのは、macOS が SIGPIPE を閉じたパイプに書き込むのではなく、メインスレッドに渡すからです.
runtime/pprof
生成されたプロファイルには、インラインマークに使用される擬似 PC は含まれなくなりました. インライン関数のシンボル情報は、pprof ツールが想定するフォーマットでエンコードされます. これは、最近のリリースで導入されたリグレッションの修正です.
strconv
NumError 型に、変換が失敗した理由を取得するのに使える Unwrap メソッドが追加されました. これは、根本のエラーが strconv.ErrRange なのか、strconv.ErrSyntax なのかを確認することに、errors.Is で NumError の値を使うことをサポートします.
sync
非常に競合の激しい Mutex をロック解除すると、その Mutex を待っている次の goroutine に直接 CPU が渡されるようになりました. これにより、CPU 数の多いマシンで、競合の多い mutex のパフォーマンスが大幅に向上しました.
testing
テストまたはベンチマークの終了後に対応する T.Cleanup または B.Cleanup を呼ぶことによって、テストパッケージはクリーンアップ機能をサポートしました.
text/template
text/template パッケージは、括弧で括られた引数が関数として使用されているときに、エラーを正しく報告するようになりました. これは、{{if (eq .F "a") or (eq .F "b")}} のような誤ったケースで最もよく見られます. これは {{if or (eq .F "a") (eq .F "b")}} と書かれなくてはなりません. 誤ったケースは期待どおりには動作せず、エラー can't give argument to non-function で報告されます.
JSEscape は、HTML の文脈で出力が誤用された場合の影響を軽減するために、& と = の文字をエスケープするようになりました.
unicode
unicode パッケージとシステム全体の関連サポートは Unicode 11.0 から、新たに4つのスクリプトを含む554の文字と61の絵文字を追加する Unicode 12.0 にアップグレードされました.