Go 1.14 リリースノート

Go 1.14 の紹介

最新の Go リリースであるバージョン 1.14 は、Go 1.13 から 6 か月後にリリースされました。変更のほとんどは、ツールチェーン、ランタイム、およびライブラリの実装にあります。いつものように、このリリースは Go 1 の互換性の約束を維持します。ほとんどすべての Go プログラムが以前と同様にコンパイルおよび実行されることを期待しています。

go コマンドのモジュールサポートが本番環境での使用に対応しました。すべてのユーザーが依存関係管理のために Go モジュールに移行することをお勧めします。Go ツールチェーンの問題により移行できない場合は、その問題に関する未解決の issue が提出されていることを確認してください。(issue が Go1.15 マイルストーンに含まれていない場合は、移行を妨げている理由をお知らせください。優先度を適切に設定するために役立ちます。)

言語の変更

重複インターフェースに関する提案に従い、Go 1.14 では、メソッドセットが重複するインターフェースの埋め込みが許可されるようになりました。埋め込みインターフェースのメソッドは、(埋め込み) インターフェースにすでに存在するメソッドと同じ名前と同一のシグネチャを持つことができます。これにより、通常は(排他的ではありませんが)ダイヤモンド型の埋め込みグラフで発生する問題が解決します。インターフェースで明示的に宣言されたメソッドは、以前と同様に一意である必要があります。

ポート

Darwin

Go 1.14 は、macOS 10.11 El Capitan で実行される最後のリリースです。Go 1.15 では、macOS 10.12 Sierra 以降が必要になります。

Go 1.14 は、macOS (darwin/386 ポート) で 32 ビットバイナリをサポートする最後の Go リリースです。macOS 10.15 (Catalina) 以降ではサポートされなくなりました。Go は、64 ビットの darwin/amd64 ポートを引き続きサポートします。

Go 1.14 は、iOS、iPadOS、watchOS、および tvOS (darwin/arm ポート) で 32 ビットバイナリをサポートする最後の Go リリースになる可能性があります。Go は、64 ビットの darwin/arm64 ポートを引き続きサポートします。

Windows

Windows 上の Go バイナリで、DEP (データ実行防止) が有効になりました。

Windows では、os.OpenFile を使用してos.O_CREATE フラグ付きで、または syscall.Open を使用してsyscall.O_CREAT フラグ付きでファイルを作成すると、パーミッション引数でビット 0o200 (所有者の書き込み権限) が設定されていない場合、ファイルが読み取り専用として作成されます。これにより、Windows での動作が Unix システムでの動作に近づきます。

WebAssembly

js.Value オブジェクトを介して Go から参照される JavaScript 値をガベージコレクションできるようになりました。

js.Value 値は、== 演算子を使用して比較できなくなり、代わりに Equal メソッドを使用して比較する必要があります。

js.ValueIsUndefinedIsNull、および IsNaN メソッドが追加されました。

RISC-V

Go 1.14 には、Linux 上の 64 ビット RISC-V (GOOS=linuxGOARCH=riscv64) の実験的なサポートが含まれています。パフォーマンス、アセンブリ構文の安定性、および場合によっては正確性が開発中であることに注意してください。

FreeBSD

Go は、FreeBSD 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 ファイルが読み取り専用であり、トップレベルの vendor ディレクトリが存在しない場合、-mod=readonly がデフォルトで設定されるようになりました。

-modcacherw は、go コマンドに、新しく作成されたモジュールキャッシュ内のディレクトリを、読み取り専用にするのではなく、デフォルトのパーミッションのままにするように指示する新しいフラグです。このフラグを使用すると、テストや他のツールが、モジュールの検証済みチェックサムに含まれていないファイルを誤って追加する可能性が高くなります。ただし、(go clean -modcache の代わりに) rm -rf を使用してモジュールキャッシュを削除できるようになります。

-modfile=file は、go コマンドに、モジュールルートディレクトリ内のファイルではなく、代替の go.mod ファイルを読み取り (および場合によっては書き込み) するように指示する新しいフラグです。モジュールルートディレクトリを決定するには、go.mod という名前のファイルがまだ存在している必要がありますが、アクセスはされません。-modfile が指定されている場合は、代替の go.sum ファイルも使用されます。そのパスは、-modfile フラグから .mod 拡張子を削除し、.sum を追加することによって派生します。

環境変数

GOINSECURE は、go コマンドに、特定のモジュールをオリジンから直接フェッチする際に、HTTPS 接続を必要とせず、証明書検証をスキップするように指示する新しい環境変数です。既存の GOPRIVATE 変数と同様に、GOINSECURE の値は、カンマ区切りの glob パターンのリストです。

モジュール外のコマンド

モジュール認識モードが明示的に有効になっている場合 (GO111MODULE=on を設定することにより)、go.mod ファイルが存在しない場合、ほとんどのモジュールコマンドの機能が制限されます。たとえば、go buildgo run、およびその他のビルドコマンドは、標準ライブラリ内のパッケージと、コマンドラインで .go ファイルとして指定されたパッケージのみをビルドできます。

以前は、go コマンドは各パッケージパスをモジュールの最新バージョンに解決していましたが、モジュールパスまたはバージョンを記録していませんでした。これにより、遅く、再現性のないビルドが発生していました。

go get は以前と同様に機能し続け、go mod downloadgo 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 コマンドは、go ディレクティブの欠落または誤った // indirect コメントが原因で失敗しなくなりました。

モジュールのダウンロード

go コマンドは、モジュールモードで Subversion リポジトリをサポートするようになりました。

go コマンドには、モジュールプロキシおよびその他の HTTP サーバーからのプレーンテキストのエラーメッセージのスニペットが含まれるようになりました。エラーメッセージは、有効な UTF-8 であり、グラフィック文字とスペースのみで構成されている場合にのみ表示されます。

テスト

go test -v は、すべてのテストの終了時ではなく、発生時に t.Log 出力をストリームするようになりました。

ランタイム

このリリースでは、ほとんどの defer の使用のパフォーマンスが向上し、遅延関数を直接呼び出すのと比較してほぼゼロのオーバーヘッドになりました。その結果、defer をオーバーヘッドを気にせずにパフォーマンスが重要なコードで使用できるようになりました。

ゴルーチンは非同期的にプリエンプト可能になりました。その結果、関数呼び出しのないループは、スケジューラをデッドロックしたり、ガベージコレクションを大幅に遅らせたりする可能性がなくなりました。これは、windows/armdarwin/armjs/wasm、および plan9/* を除くすべてのプラットフォームでサポートされています。

プリエンプションの実装の結果として、Linux および macOS システムを含む Unix システムでは、Go 1.14 でビルドされたプログラムは、以前のリリースでビルドされたプログラムよりも多くのシグナルを受け取ります。つまり、syscallgolang.org/x/sys/unix などのパッケージを使用するプログラムでは、EINTR エラーで失敗する低速なシステム呼び出しが多くなります。これらのプログラムは、何らかの方法でこれらのエラーを処理する必要があります。ほとんどの場合、ループしてシステムコールを再度試行します。詳細については、Linux システムの場合はman 7 signal を参照するか、他のシステムについては同様のドキュメントを参照してください。

ページアロケータはより効率的になり、GOMAXPROCS の高い値でのロック競合が大幅に少なくなります。これは、並行して高頻度で実行される大規模な割り当ての場合に、より低いレイテンシーと高いスループットとして最も顕著に現れます。

time.Aftertime.Ticknet.Conn.SetDeadline などで使用される内部タイマーは、ロック競合が少なく、コンテキストスイッチが少ないため、より効率的です。これは、ユーザーが認識できる変更を引き起こさないパフォーマンスの向上です。

コンパイラ

このリリースでは、Goコードがunsafe.Pointerの安全規則に動的に従っているかをチェックするためのインストルメンテーションを追加するコンパイル時オプションとして-d=checkptrが追加されました。このオプションは、-raceまたは-msanフラグが指定された場合、デフォルトで有効になります(Windowsを除く)。-gcflags=all=-d=checkptr=0で無効にできます。具体的には、-d=checkptrは以下をチェックします。

  1. unsafe.Pointer*Tに変換する場合、結果のポインタはTに対して適切にアラインされている必要があります。
  2. ポインタ演算の結果がGoのヒープオブジェクトを指している場合、unsafe.Pointer型のオペランドのいずれかが同じオブジェクトを指している必要があります。

-d=checkptrは、標準ライブラリで誤ったアラートが発生するため、現時点ではWindowsでの使用は推奨されません。

コンパイラは、インライン化、エスケープ分析、境界チェックの削除、およびnilチェックの削除を含む、主要な最適化の機械可読ログを-jsonフラグを使用して出力できるようになりました。

詳細なエスケープ分析診断(-m=2)が再び機能するようになりました。これは、前のリリースの新しいエスケープ分析実装から削除されていました。

macOSバイナリ内のすべてのGoシンボルは、プラットフォームの規約に従って、アンダースコアで始まるようになりました。

このリリースには、ファジング用のコンパイラ挿入によるカバレッジインストルメンテーションの実験的なサポートが含まれています。詳細については、issue 14565を参照してください。このAPIは将来のリリースで変更される可能性があります。

境界チェックの削除は、スライス作成からの情報を使用するようになり、intより小さい型のインデックスのチェックを削除できます。

標準ライブラリ

新しいバイトシーケンスハッシュパッケージ

Go 1.14には、バイトシーケンスのハッシュ関数を提供する新しいパッケージ、hash/maphashが含まれています。これらのハッシュ関数は、ハッシュテーブルや、任意の文字列またはバイトシーケンスを符号なし64ビット整数で均一に分布させる必要がある他のデータ構造を実装するために使用することを目的としています。

ハッシュ関数は衝突耐性がありますが、暗号学的に安全ではありません。

特定のバイトシーケンスのハッシュ値は、単一のプロセス内では一貫していますが、異なるプロセスでは異なります。

ライブラリへの小さな変更

いつものように、Go 1の互換性の約束を念頭に置いて、ライブラリにさまざまな小さな変更と更新が行われています。

crypto/tls

SSLバージョン3.0(SSLv3)のサポートが削除されました。SSLv3はTLSより前の暗号学的に破損したプロトコルであることに注意してください。

TLS 1.3は、GODEBUG環境変数を使用して無効にできなくなりました。TLSバージョンを設定するには、Config.MaxVersionフィールドを使用してください。

Config.Certificatesフィールドを介して複数の証明書チェーンが提供される場合、ピアと互換性のある最初の証明書チェーンが自動的に選択されるようになりました。これにより、例えば、ECDSA証明書とRSA証明書を提供し、パッケージに最適なものを自動的に選択させることができます。この選択のパフォーマンスは、Certificate.Leafフィールドが設定されていない限り、悪くなることに注意してください。特定の名前を単一の証明書に関連付けることのみをサポートするConfig.NameToCertificateフィールドは、非推奨になり、nilのままにしておく必要があります。同様に、リーフ証明書からNameToCertificateフィールドを作成するConfig.BuildNameToCertificateメソッドは非推奨となり、呼び出すべきではありません。

新しいCipherSuites関数とInsecureCipherSuites関数は、現在実装されている暗号スイートのリストを返します。新しいCipherSuiteName関数は、暗号スイートIDの名前を返します。

新しい(*ClientHelloInfo).SupportsCertificateメソッドと(*CertificateRequestInfo).SupportsCertificateメソッドは、ピアが特定の証明書をサポートするかどうかを公開します。

tlsパッケージは、レガシーのNext Protocol Negotiation(NPN)拡張機能をサポートしなくなり、ALPNのみをサポートするようになりました。以前のリリースでは、両方をサポートしていました。APIの変更はなく、アプリケーションは以前と同様に機能します。他のほとんどのクライアントとサーバーは、標準化されたALPNを支持して、すでにNPNサポートを削除しています。

RSA-PSS署名は、TLS 1.2ハンドシェイクでサポートされている場合に使用されるようになりました。これはほとんどのアプリケーションには影響しませんが、RSA-PSS署名をサポートしていないカスタムのCertificate.PrivateKey実装では、新しいCertificate.SupportedSignatureAlgorithmsフィールドを使用して無効にする必要があります。

Config.CertificatesConfig.GetCertificateは、Config.GetConfigForClientが設定されている場合、両方ともnilにすることができます。コールバックが証明書もエラーも返さない場合、unrecognized_nameが送信されるようになりました。

新しいCertificateRequestInfo.Versionフィールドは、クライアント証明書コールバックにTLSバージョンを提供します。

新しいTLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256定数とTLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256定数は、以前はTLS_ECDHE_RSA_WITH_CHACHA20_POLY1305およびTLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305と呼ばれていた暗号スイートの最終名を使用します。

crypto/x509

Certificate.CreateCRLは、Ed25519発行者をサポートするようになりました。

debug/dwarf

debug/dwarfパッケージは、DWARFバージョン5の読み取りをサポートするようになりました。

新しいメソッド(*Data).AddSectionは、入力ファイルからの任意の新しいDWARFセクションをDWARF Dataに追加することをサポートします。

新しいメソッド(*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で型をラップすることを検討してください。

Unmarshalは、encoding.TextUnmarshalerを実装する文字列の基になる型を持つマップキーをサポートできるようになりました。

go/build

Context型には、ビルドの作業ディレクトリを設定するために使用できる新しいフィールドDirがあります。デフォルトは、実行中のプロセスの現在のディレクトリです。モジュールモードでは、これはメインモジュールを見つけるために使用されます。

go/doc

新しい関数NewFromFilesは、*ast.Fileのリストからパッケージドキュメントを計算し、例を適切なパッケージ要素に関連付けます。新しい情報は、PackageType、およびFunc型の新しいExamplesフィールドと、Example型の新しいSuffixフィールドで利用できます。

io/ioutil

TempDirは、名前が予測可能なプレフィックスとサフィックスを持つディレクトリを作成できるようになりました。TempFileと同様に、パターンに「*」が含まれている場合、ランダムな文字列は最後の「*」を置き換えます。

log

新しいLmsgprefixフラグは、ログ関数に、行の先頭ではなく、ログメッセージの直前にオプションの出力プレフィックスを出力するように指示するために使用できます。

math

新しいFMA関数は、x*y計算の中間丸めなしに、浮動小数点数でx*y+zを計算します。いくつかのアーキテクチャでは、追加のパフォーマンスのために専用のハードウェア命令を使用してこの計算を実装しています。

math/big

GCDメソッドは、入力abがゼロまたは負であることを許可するようになりました。

math/bits

新しい関数RemRem32、および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では、CTRL_CLOSE_EVENTCTRL_LOGOFF_EVENT、およびCTRL_SHUTDOWN_EVENTイベントは、Control-CおよびControl-Breakがsyscall.SIGINT信号を生成する方法と同様に、syscall.SIGTERM信号を生成するようになりました。

plugin

pluginパッケージは、freebsd/amd64をサポートするようになりました。

reflect

StructOfは、StructField要素にPkgPathフィールドを設定することにより、非エクスポートフィールドを持つ構造体型を作成できるようになりました。

runtime

runtime.Goexitは、再帰的なpanic/recoverによって中断されなくなりました。

macOSでは、SIGPIPEは、Goランタイムが初期化される前にインストールされたシグナルハンドラーに転送されなくなりました。これは、macOSが、閉じたパイプに書き込むスレッドではなく、メインスレッドにSIGPIPEを配信するため、必要です。

runtime/pprof

生成されたプロファイルには、インラインマークに使用される擬似PCが含まれなくなりました。インライン関数のシンボル情報は、pprofツールが期待する形式でエンコードされます。これは、最近のリリースで導入されたリグレッションの修正です。

strconv

NumError 型に、変換が失敗した理由を取得するために使用できる Unwrap メソッドが追加されました。これにより、NumError の値を errors.Is と組み合わせて使用し、根本的なエラーが strconv.ErrRange または strconv.ErrSyntax であるかどうかを確認できます。

sync

競合の激しい Mutex のロック解除が、その Mutex を待機している次のゴルーチンに直接 CPU を譲るようになりました。これにより、CPUコア数の多いマシンでの、競合の激しいミューテックスのパフォーマンスが大幅に向上します。

testing

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 から Unicode 12.0 にアップグレードされました。これにより、4つの新しいスクリプト、61の新しい絵文字を含む554の新しい文字が追加されました。