Edited at

Go 1.12 リリースノート

この記事は https://golang.org/doc/go1.12 を日本語訳したものです. 次のバージョンはこちら: Go 1.13 リリースノート


Go 1.12 の紹介

最新の Go リリース、バージョン 1.12 は、Go 1.11 から6か月後に届きます. その変更点のほとんどは、ツールチェーン、ランタイム、およびライブラリの実装になります. いつものように、このリリースは Go 1 の互換性の約束を守っています. 私たちは、ほとんどすべての Go プログラムが以前と同じようにコンパイルと実行し続けることを期待しています.


言語への変更

言語仕様への変更はありません.


ポート

競合検出器(race detector)が linux/arm64 でサポートされました.

Go 1.12 はすでに EoL になっている FreeBSD 10.x をサポートする最後のリリースです. Go 1.13 では FreeBSD 11.2 以降または FreeBSD 12.0 以降が必要になります. FreeBSD 12.0 以降では COMPAT_FREEBSD11 オプションセットが有効(デフォルト状態です)なカーネルが必要です.

cgo が linux/ppc64 でサポートされました.

hurd は今は gccgoで使用するために GNU/Hurd システム用に予約されている、GOOS のための認識された値です.


Windows

Go の新しい windows/arm ポートは、Raspberry Pi 3 などの 32ビットARMチップ上の Windows 10 IoT Core で Go の動作をサポートします.


AIX

Go は、POWER8アーキテクチャー(aix/ppc64)上で AIX 7.2 以降をサポートしました. 外部リンク、cgo、pprof、および競合検出器(race detector)はまだサポートしていません.


Darwin

Go 1.12 は macOS 10.10 Yosemite で動く最後のリリースです. Go 1.13 では macOS 10.11 El Capitan 以降が必要になります.

libSystem は、Darwin でシステムコールを作成するときに使用されるようになり、macOS と iOS の将来のバージョンの前方互換性を保証します. libSystem への切り替えにより、App Store でプライベート API の使用がさらにチェックされます. 非公開と見なされるため、syscall.Getdirentries は iOS 上において ENOSYS で常に失敗します.


ツール


go tool vet は最早サポートされません

go vet コマンドは、さまざまなソースコード解析ツールのベースとして機能するように書き直されました. 詳細はgolang.org/x/tools/go/analysis パッケージを参照してください. 副作用で go tool vet がサポートされなくなりました. go tool vet を使用する外部ツールは go vet を使用するように変更しなければなりません. go tool vet の代わりに go vet を使えば、全てのサポートが切れていないバージョンの Go で動作するはずです.

この変更の一環として、実験的な -shadow オプションは go vet で使用できなくなりました. 変数シャドーイングのチェックは、以下で行えます.

go get -u golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow

go vet -vettool=$(which shadow)


Tour

Go tour はメインバイナリ配布物にもう含まれません. tour をローカルで実行するためには、go tool tourを実行する代わりに、手動インストールしてください:

go get -u golang.org/x/tour

tour


ビルドキャッシュの要件

ビルドキャッシュ$GOPATH/pkg を取り除くためのステップとして必要です. 環境変数に GOCACHE=off を設定すると、キャッシュに書き込む go コマンドが失敗します.


バイナリオンリーパッケージ

Go 1.12 はバイナリオンリーパッケージをサポートする最後のリリースです.


Cgo

Go 1.12 は C 言語の型 EGLDisplay を Go 言語の型 uintptr に変換するようになりました. Go 1.10 以降が Darwin の CoreFoundation と Java の JNI 型をどのように扱うかと、この変更は似ています. 詳しくは cgo のドキュメントを参照してください.

マングル化されている C の名前は Cgo を使っているパッケージの中では受け入れられなくなりました. 代わりに Cgo の名前を使用してください. 例えば、cgo が生成するマングル化された名前 _Ctype_char ではなく、文書化された cgo 名 C.char を使用します.


モジュール

GO111MODULEon に設定されている場合、操作が現在のディレクトリに対する相対的なインポートパスを解決する必要があったり、go.mod ファイルを明示的に編集したりする必要がない限り、go コマンドはモジュールディレクトリの外でモジュールを認識した操作をサポートするようになりました. go getgo listgo mod download などのコマンドは、初期の空の要件を持つモジュール内にあるかのように動作します. このモードでは、go env GOMOD はシステムのnull デバイス (/dev/null または NUL) を報告します.

モジュールをダウンロードして抽出する go コマンドは、複数同時に起動しても安全になりました. モジュールキャッシュ (GOPATH/pkg/mod) はファイルロックをサポートするファイルシステムに存在する必要があります.

go.mod ファイルの go ディレクティブは、そのモジュール内のファイルで使用されている言語のバージョンを示します. 既存のバージョンが存在しない場合は、現在のリリース(go 1.12)に設定されます. モジュールの go ディレクティブが使用中のツールチェーンよりも新しいバージョンを指定している場合、go コマンドはそれに関わらずパッケージの構築を試み、失敗した場合にのみ不一致を示します.

アクティブなモジュールを使ってインポートを解決できない場合、go コマンドはモジュールキャッシュと通常のネットワークソースを調べる前に、メインモジュールの replace ディレクティブに記載されているモジュールを使おうとするようになりました. 一致する置換が見つかったが replace ディレクティブがバージョンを指定していない場合、go コマンドはゼロ time.Time (v0.0.0-00010101000000-000000000000 など) から派生した疑似バージョンを使用します.


コンパイラツールチェーン

コンパイラの変数の生死解析が改善されました. このことは以前のリリースよりもこのリリースで、ファイナライザがより早く実行されうることを意味します. もしそれが問題であれば、runtime.KeepAlive の呼び出しを適切に追加することを検討してください.

他の関数を呼び出す以外に何もしない関数を含め、より多くの関数がデフォルトでインライン化の対象になりました. この追加のインライン化により、直接 runtime.Callers の結果を反復する代わりに、runtime.CallersFrames を使用することがより重要になります.

// 最早正しく動かない古いコード (インライン化されたコールフレームを見逃す).

var pcs [10]uintptr
n := runtime.Callers(1, pcs[:])
for _, pc := range pcs[:n] {
f := runtime.FuncForPC(pc)
if f != nil {
fmt.Println(f.Name())
}
}

// 正しく動く新しいコード.
var pcs [10]uintptr
n := runtime.Callers(1, pcs[:])
frames := runtime.CallersFrames(pcs[:n])
for {
frame, more := frames.Next()
fmt.Println(frame.Function)
if !more {
break
}
}

メソッド式を実装するためにコンパイラによって生成されたラッパーは、runtime.CallersFramesおよびruntime.Stackでは報告されなくなりました. それらはパニックスタックトレースにも表示されません.

これは、すでにスタックトレースからそのようなラッパーを取り除いた gccgo ツールチェーンと一致するよう gc ツールチェーンを変更するものです.

これらの API のクライアントは、失われたフレームを調整する必要があるかもしれません. 1.11 と 1.12 の間で相互運用する必要があるコードの場合、メソッド式 x.M を関数リテラル func(...){ x.M(...)} に置き換えることができます.

コンパイラは、使用する Go 言語のバージョンを設定するための -lang フラグを受け入れるようになりました. たとえば、-lang=go1.8 を指定して、Go 1.9 で追加されたタイプエイリアスをプログラムで使用すると、コンパイルエラーになります. Go 1.12 以前に行われた言語の変更は、一貫して強制されていません.

コンパイラツールチェーンは、Go 関数とアセンブリ関数を呼び出しに異なるコンベンションを使うようになりました. Go とアセンブリの間およびパッケージの境界をまたぐ呼び出しを除いて、これはユーザーには見えないはずです. リンクの結果、 "relocation target not defined for ABIInternal (but is defined for ABI0)" のようなエラーが発生した場合には、ABI 設計ドキュメントの互換性セクションを参照してください.

引数の表示や変数の位置情報の改善などを含め、コンパイラによって生成される DWARF デバッグ情報に多くの改善が行われました.

perf のようなプロファイリングツールの利点のために、linux/arm64 上のスタックフレームポインタも、Go プログラムは維持するようになりました. フレームポインタの維持には、実行時のオーバーヘッドがわずかにありますが、平均 3% 程度です. フレームポインタを使用しないツールチェーンを構築するには、make.bash を実行するときにGOEXPERIMENT=noframepointer を設定します.

旧式の "safe" コンパイラモード(-u gcflag で有効にできる)は削除されました.


godocgo doc

Go 1.12 では、godoc はもはやコマンドラインインターフェースを持っておらず、Web サーバーのみです. ユーザは代わりとして、コマンドラインヘルプの出力に go doc を使うべきです. Go 1.12 は godoc Web サーバーを含む最後のリリースです. Go 1.13 では、go get を介して利用するようになる予定です.

godoc コマンドラインがそうしていたように、全てのエクスポートされた API とそのドキュメントが出力される、-all フラグを go doc はサポートするようになりました.

また、go doc は対象のソースコードを表示する -src フラグを持つようになりました.


トレース

トレースツールは、実行トレースへの相互参照を含む、ミューテーター利用率曲線のプロットをサポートしました. アプリケーションのレイテンシとスループットに対するガベージコレクタの影響を分析するのにこれらは有益です.


アセンブラ

arm64 では、OS がこのレジスタを予約する可能性があるため、誤って使用されないように、プラットフォームレジスタは R18 から R18_PLATFORM にリネームされました.


ランタイム

Go 1.12 はヒープの大部分が生存のままであるときのスイープのパフォーマンスが大幅に改善しています. これはガベージコレクション直後のメモリ割り当てのレイテンシを削減します.

特に既存のヒープ領域を再利用できない大きな割り当てに対して、Go ランタイムはメモリをより積極的にオペレーティングシステムに返却するようになりました.

Go ランタイムのタイマーとデッドラインコードはより多い CPU 数でより高速に、よりスケールするようになりました. 特にネットワーク接続のデッドラインの操作のパフォーマンスが改善しています.

Linux で、ランタイムは未使用のメモリの解放に MADV_FREE を使用するようになりました. これはより効率的ですが、報告される RSS が高くなる可能性があります. カーネルは未使用のデータが必要なときに回収します. Go 1.11 の挙動(MADV_DONTNEED)に戻すには、環境変数に GODEBUG=madvdontneed=1 を設定します.

GODEBUG 環境変数に cpu.extension=off を追加すると、標準ライブラリとランタイムでのオプションの CPU 命令セット拡張で使用されるのが無効になりました. これは Windows ではまだサポートされていません.

Go 1.12では、大きなヒープ割り当てのオーバーカウントを修正することでメモリプロファイルの精度が向上しました.

Tracebacks、runtime.Caller、およびruntime.Callersに、コンパイラ生成の初期化関数が含まれなくなりました. グローバル変数の初期化中にトレースバックを実行すると、PKG.init.ializersという名前の関数が表示されます.


コアライブラリ


TLS 1.3

Go 1.12 では、RFC 8446 で規定された TLS 1.3 のオプトインサポートを crypto/tls パッケージに追加しています. それは GODEBUG 環境変数に tls13=1 を追加することで有効にできます. Go 1.13 ではデフォルトで有効になります.

TLS 1.3 でネゴシエートするには、Config で明示的に MaxVersion を設定せずに、環境変数に GODEBUG=tls13=1 を設定して、あなたのプログラムを走らせてください.

ConnectionStateTLSUnique と再ネゴシエーションを除くすべての TLS 1.2 機能は TLS 1.3 で使用可能であり、同等以上のセキュリティとパフォーマンスを提供します. TLS 1.3 は以前のバージョンと後方互換性がありますが、それをネゴシエートしようとするとある種のレガシシステムは正しく動作しない可能性があることに留意してください. 安全には程遠い小さすぎるRSA証明書鍵(512ビット鍵を含む)は TLS 1.3 では使えません.

TLS 1.3 暗号スイートは設定できません. サポートされているすべての暗号スイートは安全で、PreferServerCipherSuitesConfig で設定されている場合、優先順位は利用可能なハードウェアに基づきます.

初期データ("0-RTTモード" とも呼ばれる)は、現在はクライアントとしてもサーバーとしてもサポートされていません. さらに Go 1.12 サーバーは、クライアントが送信した場合、予期しない初期データのスキップをサポートしていません. TLS 1.3 0-RTT モードでは、どのサーバーが 0-RTT をサポートしているかについてクライアントが状態を保持するので、Go 1.12 サーバーは他のサーバーが 0-RTT をサポートしているロードバランシングプールの一部にはなれません. 0-RTT をサポートするサーバーから Go 1.12 サーバーにドメインを切り替える場合、操作が中断されないことを保証するために、少なくとも切り替え前に発行されたセッションチケットの存続期間中 0-RTT を無効にする必要があります.

TLS 1.3 では、ハンドシェイクで最後に話すのはクライアントなので、サーバーでエラーが発生した場合、ハンドシェイクではなく最初の読み込み でエラーがクライアントに返されます. たとえばサーバーがクライアント証明書を拒否したなどです. 同様にセッションチケットはハンドシェイク後のメッセージになり、クライアントは最初の読み込み時にのみ受信します.


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

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


bufio

Peek の後に呼び出された場合、Reader の UnreadRune メソッドと UnreadByte メソッドはエラーを返すようになりました.


bytes

新しい関数 ReplaceAll は、値の重複していないすべてのインスタンスを別のバイトスライスに置き換えて、バイトスライスのコピーを返します.

ゼロ値の Reader へのポインタは、機能的には NewReader(nil) と同等となりました. Go 1.12 より前では、前者は完全には後者の代替とはなりませんでした.


crypto/rand

Reader.Read がカーネルからエントロピーを読むのを待っている間60秒以上ブロックされた最初のときに、警告が標準エラーに出力されるようになりました.

FreeBSDでは、Reader は利用可能ならば getrandom システムコールを、そうでなければ /dev/urandom を使うようになりました.


crypto/rc4

このリリースではアセンブリの実装が削除され、純粋な Go バージョンのみが残されています. Go コンパイラの生成するコードは、CPU に依りますが、ちょっと良かったり悪かったりします. RC4 は安全ではないため、レガシーシステムとの互換性のためだけに使用してください.


crypto/tls

クライアントが TLS のように見えない初期メッセージを送信した場合、サーバーはアラートで応答しなくなり、RecordHeaderError の新しいフィールドで、基礎となる net.Conn にそれを露出します.


database/sql

クエリカーソルは、Row.Scan メソッドに *Rows の値を渡すことで取得できるようになりました.


expvar

新しい Delete メソッドでは、Map からキーと値のペアを削除できます.


fmt

テストを容易にするために、マップはキー順に印刷されるようになりました. 順序付け規則は:


  • 該当する場合、nil は最低として比較します

  • 整数、浮動小数点数、文字列は < で並べます

  • NaN は NaN でない浮動小数点数より小さいものとして比較します

  • ブールは true の前に false として比較します

  • 複素数は実数の後に虚数を比較します

  • ポインタはマシンアドレスで比較します

  • チャネルの値はマシンアドレスで比較します

  • 構造体は各フィールドを順番に比較します

  • 配列は各要素を順番に比較します

  • インタフェース値は、最初に reflect.Type によって具体的な型で比較し、次に具体的な値によって前述の規則で説明されているように比較します

map を表示するとき、NaN のような非反射キー値は以前は <nil> として表示されていました. このリリースでは、正しい値が表示されます.


go/doc

cmd/doc のいくつかの未解決の問題に対処するために、このパッケージには、ASTデータを消去するかどうかを制御する、新しい Mode ビット、PreserveAST を持つようになりました.


go/token

File 型は、与えられた行の開始位置を返す新しい LineStart フィールドを持つようになりました. これは、アセンブリなど、Go 以外のファイルをときどき処理するプログラムで特に便利ですが、ファイルの位置を識別するのは token.Pos メカニズムを使用することを希望します.


image

RegisterFormat 関数はコンカレントな利用に安全になりました.


image/png

16色以下のパレットカラー画像のエンコード出力がより小さくなりました.


io

新しい StringWriter インターフェースが WriteString 関数をラップします.


lib/time

$GOROOT/lib/time/zoneinfo.zip のタイムゾーンデータベースがバージョン2018iに更新されました. この ZIP ファイルは、タイムゾーンデータベースがオペレーティングシステムによって提供されていない場合にのみ使用されることに注意してください.


math

関数 SinCosTan、および Sincos は Payne-Hanek の範囲縮小を大きな引数に適用するようになりました. これにより、より正確な答えが得られますが、以前のリリースの結果と少しずつは一致しません.


math/bits

新しい拡張精度演算 AddSubMulDivuintuint32uint64 で利用可能になりました.


net

Dialer.DualStack 設定は無視されるようになり、非推奨になりました. RFC 6555 Fast Fallback ("Happy Eyeballs") がデフォルトで有効になりました. 無効にするには、Dialer.FallbackDelay を負の値に設定します.

同様に、Dialer.KeepAlive がゼロの場合、TCP キープアライブはデフォルトで有効になりました. 無効にするには、負の値に設定します.

Linux では、UnixConnから TCPConn にコピーするときに splice システムコールが使用されるようになりました.


net/http

HTTP サーバはプレーンテキストの "400 Bad Request" 応答で HTTPS サーバ への誤ったHTTP 要求を拒否するようになりました.

新しい Client.CloseIdleConnections メソッドは、Client の基礎となる TransportCloseIdleConnections がある場合はそれを呼び出すようになりました.

Transport は、HTTP Trailers を宣言する HTTP 応答を拒否しなくなりましたが、チャンクエンコーディングは使用しません. 代わりに、宣言された HTTP Trailers をただ無視するようになりました.

Transport は、Go 1.10~1.11 のように厳密には、HTTP/2 サーバーからアドバタイズされた MAX_CONCURRENT_STREAMS 値を取り扱わなくなりました. デフォルトの動作は Go 1.9 に戻りました. サーバーへの各接続は最大 MAX_CONCURRENT_STREAMS 要求をアクティブにすることができ、その後必要に応じて新しいTCP接続が作成されます. Go 1.10 と Go 1.11 では、http2 パッケージは新しい接続を作成する代わりにブロックしてリクエストが終了するのを待ちます. より厳密な動作に戻すには、golang.org/x/net/http2 パッケージを直接インポートし、Transport.StrictMaxConcurrentStreamstrue に設定します.


net/url

ParseParseRequestURI、およびURL.Parseは、NULL、タブ、および改行を含むASCII制御文字を含むURLに対してエラーを返すようになりました.


net/http/httputil

ReverseProxy は WebSocket のリクエストを自動的にプロキシーするようになりました.


os

新しい ProcessState.ExitCode メソッドは、プロセスの終了コードを返します.

ModeTypeで FileMode をマスクするときに、ModeDevice | ModeCharDevice で回復することを許すために、ModeCharDeviceModeType ビットマスクに追加されました.

新しい関数 UserHomeDir は、現在のユーザーのホームディレクトリを返します.

RemoveAll はほとんどの Unix システムで4096文字を超えるパスをサポートするようになりましました.

File.Sync は、macOS で F_FULLFSYNC を使用してファイルの内容を永続記憶に正しくフラッシュするようになりました. これにより、メソッドの実行速度が以前のリリースより遅くなる可能性があります.

File は、syscall.RawConn インターフェイス値を返す SyscallConn メソッドをサポートするようになりました. これは、基礎となるファイル記述子に対してシステム固有の操作を呼び出すために使用されることがあります.


path/filepath

IsAbs 関数は、Windows 上で NUL などの予約されたファイル名を渡されたときに true を返すようになりました. (予約名のリスト)


reflect

新しい MapIter 型は、map を走査するためのイテレータです. この型は Value型の新しい MapRange メソッドを通して公開されます. これは、範囲ステートメントと同じ繰り返しセマンティクスに従い、Next はイテレータを進め、Key/Value は各エントリにアクセスします.


regexp

ロックの競合を回避するために Copy は必要なくなったため、一部非推奨のコメントが付けられました. Copy を使用する理由が、異なる Longest 設定で2つのコピーを作成することである場合は、コピーが依然として適切である可能性があります.


runtime/debug

新しい BuildInfo 型は、モジュールサポート付きでビルドされたバイナリでのみ利用可能な、実行中のバイナリから読み込まれたビルド情報を公開します. これには、メインパッケージパス、メインモジュール情報、およびモジュールの依存関係が含まれます. この型は BuildInfoReadBuildInfo 関数を通して与えられます.


strings

新しい関数 ReplaceAll は、値の重複していないすべてのインスタンスを別のもので置き換えた文字列のコピーを返します.

ゼロ値の Reader へのポインタは、機能的には NewReader(nil) と同等となりました. Go 1.12 より前では、前者は完全には後者の代替とはなりませんでした.

新しい Builder.Cap メソッドは、ビルダーの基礎となるバイトスライスの容量を返します.

文字マッピング関数 MapTitleToLowerToLowerSpecialToTitleToTitleSpecialToUpperToUpperSpecial は有効な UTF-8 を返すことを保証するようになりました. 以前のリリースでは、入力が無効な UTF-8 で、文字置換を適用する必要がなかった場合、これらのルーチンは変更せず無効な UTF-8 を誤って返しました.


syscall

64ビットiノードが FreeBSD 12 でサポートされるようになりました. いくつかの型はそれに応じて調整されました.

Unix ソケット (AF_UNIX) アドレスファミリは、互換性のあるバージョンの Windows でサポートされるようになりました.

新しい関数 Syscall18 が Windows 用に導入され、最大18個の引数を持つ呼び出しが可能になりました.


syscall/js

Callback 型と NewCallback 関数は改名されました. それらは現在それぞれ FuncFuncOf と呼ばれています. これは破壊的な変更ですが、WebAssembly サポートはまだ実験的なものであり、Go 1 の互換性の約束にはまだ準じていません. 古い名前を使用しているコードはすべて更新する必要があります.

型が新しい Wrapper インターフェースを実装している場合、ValueOf はそれを使用してその型の JavaScript 値を返します.

ゼロの意味が変わりました. それは今や数値のゼロではなく、JavaScript の undefined を意味します. これは破壊的な変更ですが、WebAssembly サポートはまだ実験的なものであり、Go 1 の互換性の約束にはまだ準じていません. ゼロが数値のゼロを意味することに依存するコードはすべて更新する必要があります.

新しい Value.Truthy メソッドは、与えられた値の JavaScript "truthiness" を報告します.


testing

-benchtime フラグは、"x"で終わる値のときに、明示的な反復回数の設定をサポートするようになりました. 例えば -benchtime=100x はベンチマークを100回実行します.


text/template

テンプレートを実行するときに、エラーの中で長いコンテキスト値が切り詰められなくなりました.

変更前:

executing "tmpl" at <.very.deep.context.v...>: map has no entry for key "notpresent"

変更後:

executing "tmpl" at <.very.deep.context.value.notpresent>: map has no entry for key "notpresent"

もしテンプレートによって呼び出されたユーザ定義関数がパニックになった場合、そのパニックはキャッチされ、Execute または ExecuteTemplate メソッドによってエラーとして返されるようになりました.


unsafe

nil unsafe.Pointeruintptr に変換して、算術に戻すことは無効です. (これはすでに無効でしたが、コンパイラの不正動作を引き起こすようになりました.)