Go
golang

Go 1.11 リリースノート(和訳)

この記事は https://tip.golang.org/doc/go1.11 を翻訳したものです。
[2018/08/26更新]

Go 1.11リリースノート

Go 1.11の紹介

最新のGoリリース、バージョン1.11は、Go 1.10から6ヶ月後にリリースしました。その変更のほとんどはツールチェーン、ランタイム、およびライブラリの実装にあります。いつものように、リリースはGo 1の互換性を保証しています。ほとんどすべてのGoプログラムは以前と同じようにコンパイルと実行を続けます。

言語の変更

言語仕様に変更はありません。

ポート

Go 1.10のリリースノートで発表されているように、Go 1.11にはOpenBSD 6.2以降、macOS 10.10 Yosemite、またはWindows 7以降が必要です。これらのオペレーティングシステムの以前のバージョンのサポートは削除されました。

Go 1.11は今後のOpenBSD 6.4リリースをサポートしています。 OpenBSDカーネルの変更により、古いバージョンのGoはOpenBSD 6.4では動作しません。

i386ハードウェア上のNetBSDに関しては既知の問題があります。

レースディテクタは現在、linux/ppc64leと、ある程度netbsd/amd64でもサポートされています。 NetBSDレースディテクタのサポートには既知の問題があります。

メモリサニタイザ(-msan)が、linux/arm64でサポートされるようになりました。

ビルドモードc-sharedc-archivefreebsd/amd64でサポートされるようになりました。

64ビットMIPSシステムでは、新しい環境変数設定 GOMIPS64=hardfloat (デフォルト)および GOMIPS64=softfloat は、浮動小数点計算にハードウェア命令とソフトウェアエミュレーションのどちらを使用するかを選択します。 32ビットシステムの場合、環境変数はGo 1.10で追加されたGOMIPSです。

Soft-float ARMシステム(GOARM=5)では、Goはより効率的なソフトウェア浮動小数点インターフェイスを使用します。これはGoコードに対して透過的ですが、GOARMで保護されていない浮動小数点命令を使用するARMアセンブリは中断され、新しいインタフェースに移植する必要があります。

ARMv7でのGo 1.11への移行は、KUSER_HELPERSで設定されたLinuxカーネルは不要になりました。この設定は、デフォルトのカーネル設定で有効になっていますが、必要最低限の構成では無効になることがあります。

WebAssembly

Go 1.11は、WebAssembly(js/wasm)に実験用ポートを追加します。

Goのプログラムは、goroutineスケジューリング、ガベージコレクション、マップなどのGoランタイムを含む1つのWebAssemblyモジュールにコンパイルされます。その結果、結果サイズは最小で約2MB、言い換えると500KBの圧縮です。 Goプログラムは、新しい実験的な [syscall/js(https://golang.org/pkg/syscall/js/) パッケージを使用してJavaScriptを呼び出すことができます。バイナリサイズや他の言語との相互運用性はまだ優先事項にはなっていませんが、将来のリリースで対処される可能性があります。

新しいGOOS値 "js"とGOARCH値 "wasm"が追加された結果、GOOS/GOARCH値が使用されている場合を除いて、Goツールでは *_js.go または *_wasm.go というGoファイルが無視されるようになりました。これらのパターンに一致する既存のファイル名がある場合は、名前を変更する必要があります。

詳細はWebAssemblyのwikiページを参照してください。

RISC-V GOARCH値の予約

主なGoコンパイラはまだRISC-Vアーキテクチャをサポートしていませんが、RISC-VをサポートするGccgoが使用するGOARCH値 "riscv"と "riscv64"を予約しています。つまり、GOOS/GOARCH値が使用されている場合を除いて、 *_riscv.go というGoファイルがGoツールによって無視されるようになりました

ツール

モジュール、パッケージのバージョン管理、依存関係管理

Go 1.11では、GOPATHの代わりとなる、バージョン管理とパッケージ配布のサポートを統合した「モジュール」という新しいコンセプトを、予備的にサポートしています。モジュールを使用すると、開発者はもはやGOPATH内での作業に限定されず、バージョン依存情報は明示的かつ軽量であり、ビルドはより信頼性と再現性があります。

モジュールのサポートは実験的なものとみなされます。詳細は、Go 1.11ユーザーからのフィードバックに応じて変更される可能性があり、さらにツール追加の計画もあります。モジュールのサポートの詳細は変更される可能性がありますが、Go 1.11を使用してモジュールに変換するプロジェクトは、Go 1.12以降でも引き続き動作します。モジュールを使用してバグが発生した場合は、問題を修正できるよう、イシューを報告してください。詳細はgoコマンドのドキュメントを参照してください。

インポートパスの制限

Goモジュールのサポートはコマンドライン操作で@記号に特別な意味を割り当てるので、goコマンドは@記号を含むインポートパスの使用を禁止するようになりました。そのようなインポートパスは今までもgo getによって許されてなかったので、この制限は他の手段でカスタムGOPATHツリーを構築するユーザにのみ影響します。

パッケージの読み込み

新しい golang.org/x/tools/go/packages パッケージは、Goソースコードのパッケージの検索と読み込みを行うためのシンプルなAPIを提供します。 まだ標準ライブラリには含まれていませんが、多くのタスクではAPIがモジュールを完全にサポートできない go/build パッケージを効果的に置き換えます。 Goパッケージに関する情報を得るために go list などの外部クエリーコマンドを実行するため、 BazelBuck などの代替ビルドシステムと同等に機能する解析ツールの構築が可能になります。

ビルドキャッシュの要件

Go 1.11は、Go 1.10で導入されたビルドキャッシュを無効にするために、環境変数 GOCACHE=off の設定をサポートする最後のリリースとなります。 Go 1.12以降では、$GOPATH/pkgを削除するためのステップとして、ビルドキャッシュが必須になります。上記の、モジュールおよびパッケージのロードサポートでも、ビルドキャッシュを有効にする必要があります。遭遇した問題を避けるためにビルドキャッシュを無効にしている場合は、我々が把握できるよう問題を報告してください。

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

panic を呼び出す関数を含む、より多くの関数がデフォルトでインライン展開に適格になりました。

コンパイラツールチェーンは、行ディレクティブの列情報をサポートするようになりました。

新しいパッケージエクスポートデータ形式が導入されました。これは、大規模なGoプロジェクトのビルド時間を短縮することを除いて、エンドユーザーにとって透過的でなければなりません。問題が発生した場合は、バイナリをビルドするときに -gcflags=all=-iexport=false をgoツールに渡すことで、再度オフにすることができます。

コンパイラは、次の例の x など、タイプスイッチガードで宣言されている未使用の変数を拒否します。

func f(v interface{}) {
    switch x := v.(type) {
    }
}

これはすでに gccgogo/typesの両方で拒否されていました。

アセンブラ

amd64 用のアセンブラは、AVX512命令を受け入れるようになりました。

デバッグ

コンパイラは、変数のロケーション情報、行番号、およびブレークポイントの場所を含む、最適化されたバイナリのデバッグ情報をより正確に生成します。これにより、 -N -l なしでコンパイルされたバイナリをデバッグすることが可能になります。デバッグ情報の品質にはまだ限界がありますが、そのうちのいくつかは基本的なものであり、その一部は将来のリリースで改善し続けるでしょう。

DWARFセクションは、コンパイラによって生成されたより詳細なデバッグ情報のため、デフォルトで圧縮されています。これは、ほとんどのELFツール(Linuxおよび*BSDのデバッガなど)には透過的で、すべてのプラットフォームでDelveデバッガでサポートされていますが、macOSおよびWindowsのネイティブツールではサポートが限られています。 DWARF圧縮を無効にするには、バイナリをビルドするときに -ldflags=-compressdwarf=false をgoツールに渡します。

Go 1.11では、デバッガ内からGo関数を呼び出すための実験的なサポートが追加されています。これは、たとえば、ブレークポイントで一時停止したときに String メソッドを呼び出す場合などに便利です。これは現在、Delve(バージョン1.1.0以降)でのみサポートされています。

テスト

Go 1.10以来、 go test コマンドは、テストを実行する前に問題を特定するために、 go vet を実行します。 vet typecheckは実行前にgo/typesでコードを検査するので、タイプチェックを通らないテストはfailします。特に、Goコンパイラが間違って受け入れたため(Issue#3059)Go1.10でコンパイルされたクロージャ内の未使用変数を含むテストは通ってしまっていましたが、go/types が "unused variable" エラーを正しくレポートするため、failするようになっています。

go test-memprofile フラグはデフォルトで、テストが開始されてから割り当てられた合計バイト数(ガーベジ・コレクションされたバイトを含む)を記録する "allocs" プロファイルに設定されています。

Vet

解析中のパッケージがタイプチェックを通らない場合、go vet コマンドはfatal errorを報告するようになりました。以前はタイプチェックエラーが発生すると、警告が表示され、vet がステータス1で終了するのみでした。

さらに、 go vet はprintfラッパーのフォーマットチェック時により堅牢になりました。 Vetはこの例で間違いを検出します:

func wrapper(s string, args ...interface{}) {
    fmt.Printf(s, args...)
}

func main() {
    wrapper("%s", 42)
}

Trace

新しい runtime/trace パッケージのuser annotation APIにより、ユーザーはアプリケーション・レベルの情報を実行トレースに記録し、関連するゴルーチンのグループを作成できます。 go tool traceコマンドは、この情報をトレースビューと新しいユーザータスク/領域分析ページで視覚化します。

Cgo

Go 1.10以降、cgoはいくつかのCポインタ型をGo型uintptrに変換しています。 これらの型には、DarwinのCoreFoundationフレームワークの CFTypeRef 階層とJavaのJNIインタフェースの jobject 階層が含まれます。 Go 1.11では、これらの型を検出するコードがいくつか改良されました。 これらの型を使用するコードは、更新が必要な場合があります。 詳細はGo 1.10リリースノートを参照してください。

Godoc

Go 1.11は、godocのコマンドラインインターフェイスをサポートする最後のリリースになります。 将来のリリースでは、godoc はwebサーバーだけになります。 ユーザーはコマンドラインヘルプ出力に go doc を使用するべきです。

godoc webサーバーは、Goのどのバージョンが新しいAPI機能を導入したかを表示するようになりました。 タイプ、関数、およびメソッドの最初のGoバージョンは、右揃えで表示されます。 たとえば、UserCacheDirの右側に「1.11」と表示されます。 構造体フィールドの場合、型フィールド自体が導入されたとき以外のGoバージョンで構造体フィールドが追加されたときに、インラインコメントが追加されます。 構造体フィールドの例としては、ClientTrace.Got1xxResponseを参照してください。

Gofmt

Goソースコードのデフォルト書式の小さな部分が変更されました。インラインコメント付きの式リストの書式設定では、ヒューリスティックにコメントを整列させました。しかし、場合によっては、整列があまりにも簡単に分割されるか、あまりにも多くの空白が導入されます。ヒューリスティックが、人間が書いたコードではより良く動作するように変更されています。

gofmtに対するこれらのマイナーアップデートは時々期待されることに注意してください。一般的に、Goソースコードを一貫してフォーマットする必要のあるシステムでは、特定のバージョンの gofmt バイナリを使用する必要があります。詳細はgo/formatパッケージのドキュメントを参照してください。

ランタイム

ランタイムではスパースヒープレイアウトが使用されるため、Goヒープのサイズに制限はなくなりました(以前は512GiBでした)。これはまた、混在したGo/Cバイナリや -race でコンパイルされたバイナリで、まれな "アドレス空間の競合"の不具合を修正します。

macOSとiOSでは、ランタイムはカーネルを直接呼び出す代わりに libSystem.so を使用するようになりました。これによりGoバイナリは、macOSとiOSの将来のバージョンとより互換性があります。 syscallパッケージは依然として直接システムコールを行います。これを修正することは、将来のリリースで予定されています。

パフォーマンス

いつものように、変化は非常に一般的で多様であり、パフォーマンスに関する正確な記述は難しいです。ほとんどのプログラムは、生成されたコードの改善とコアライブラリの最適化により、少し速く動作するはずです。

math/big パッケージに対するパフォーマンスの変更や、 GOARCH=arm64 に固有のツリー全体にわたる多くの変更がありました。

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

コンパイラは次の形式のマップ消去操作を最適化します。

for k := range m {
    delete(m, k)
}

コンパイラはappend(s, make([]T, n)...) という形式のスライス拡張を最適化するようになりました。

コンパイラは現在、より積極的な境界チェックと分岐削除を実行します。特に、推移関係を認識するので、 i<jj<len(s) ならば、これらの事実を使って s[i] の境界チェックを排除することができます。また、 s[i-10] のような単純な算術を理解し、ループ内のより多くの誘導事例を認識することができます。さらに、コンパイラは境界操作情報を使用して、より積極的にシフト操作を最適化します。

コアライブラリ

標準ライブラリへのすべての変更は軽微です。

ライブラリのマイナーな変更

いつものように、互換性の約束を念頭に置いて作られた、ライブラリに対する様々なマイナーな変更や更新があります。

crypto

ecdsa.Signrsa.EncryptPKCS1v15rsa.GenerateKeyなどの特定の暗号操作では、テストが内部動作に依存しないように余分なバイトがランダムに読み取られるようになりました。

crypto/cipher

新しい関数NewGCMWithTagSizeは、既存の暗号システムとの互換性のために非標準のタグ長でガロアカウンターモードを実装します。

crypto/rsa

PublicKeyはモジュラスサイズをバイト単位で返すSizeメソッドを実装するようになりました。

crypto/tls

ConnectionStateの新しい ExportKeyingMaterial フィールドでは、RFC 5705に従って接続にバインドされたキー材料をエクスポートできます。

crypto/x509

CNが有効なホスト名でない場合、Subject Alternative Namesが存在しないときにCommonNameフィールドをホスト名として扱うことは推奨されなくなりました。 CommonNameは、実験値 x509ignoreCN=1GODEBUG 環境変数に追加することで、完全に無視することができます。 CNが無視されると、SANのない証明書は、 NameConstraintsWithoutSAN を返すのではなく、名前制約のあるチェーンの下で検証します。

拡張キーの使用制限は、常にチェックされるのではなく、VerifyOptionsKeyUsages フィールドに表示される場合にのみ、再度チェックされます。これは、Go 1.9以前の動作に一致します。

SystemCertPoolが返す値はキャッシュされ、呼び出し間のシステム変更は反映されない可能性があります。

debug/elf

ELFOSABIEMの定数が追加されました。

encode/asn1

MarshalとUnmarshalは、フィールドの "private" クラスアノテーションをサポートするようになりました。

encoding/base32

デコーダは、不完全なチャンクに対して一貫して io.ErrUnexpectedEOF を返すようになりました。これまでは io.EOF を返すことがありました。

encoding/csv

Reader は、Commaフィールドにダブルクォーテーションを設定することを拒絶するようになりました。ダブルクォーテーションはすでにCSVで特別な意味を持っているためです。

go/scanner

位置情報を記録したり、エラーを報告したりするときに、パッケージは //line ディレクティブのファイル名を変更しなくなりました。これまでは、ソースファイルディレクトリを前置することによって、パッケージは //line ディレクティブの相対パスを絶対パスに変更していました。

html/template

型付きのインタフェース値が暗黙のエスケープ関数に渡されたときの、パッケージの動作が変更されました。以前は、そのような値は <nil> (のエスケープ形式)として書き出されていました。このような値は、型なしの nil 値同様、無視されます。

image/gif

ループしていないアニメーションGIFもサポートされるようになりました。それらはLoopCountが-1で表されます。

io/ioutil

TempFile関数は、ファイル名のランダムな文字の配置場所を指定できるようになりました。接頭引数に "*"が含まれている場合は、 "*"がランダム文字列に置き換えられます。たとえば、接頭引数 "myname.*.bat"は、 "myname.123456.bat"のようなランダムなファイル名になります。 "*"が含まれていない場合、古い振る舞いが保持され、ランダムな数字が末尾に追加されます。

math/big

gとnが互いに素でない場合、ModInverseはnilを返すようになりました。結果は以前は定義されていませんでした。

mime/multipart

欠落/空のファイル名を含むフォームデータの処理は、Go 1.9の動作に戻されました。フォームデータ部分のFormでは、値は File フィールドではなく Value フィールドで使用できます。 Goリリース1.10から1.10.3では、Fileフィールドに欠落/空のファイル名と空ではない "Content-Type" フィールドが含まれるフォーム・データ部分が保管されていました。この変更は1.10の間違いであり、1.9の動作に戻っています。

mime/quotedprintable

野生の無効な入力をサポートするために、パッケージは非ASCIIバイトを許可するようになりましたが、エンコーディングは検証されません。

net

新しいListenConfigタイプと新しいDialer.Controlフィールドでは、それぞれ接続を受け入れて作成する前にソケットオプションを設定できます。

syscall.RawConn ReadWrite メソッドはWindows上で正しく動作するようになりました。

netパッケージは、io.Copyによって呼び出されるTCPConn.ReadFromのTCP接続間でデータをコピーするとき、Linux上のspliceシステムコールを自動的に使用するようになりました。その結果、より高速で効率的なTCPプロキシが可能になります。

TCPConn.FileUDPConn.FileUnixConn.File、およびIPConn.Fileメソッドは、返された *os.File をブロッキングモードにしなくなりました。

net/http

Transportに、ホストごとの最大接続数を制限する新しいMaxConnsPerHostオプションが追加されました。

Cookieタイプには、最近のほとんどのブラウザでサポートされている新しいCookie属性を表す新しいフィールドSameSite(型は同様に新しいSameSite)があります。 net/httpのトランスポートでは SameSite 属性自体は使用されませんが、パッケージはブラウザの属性の解析とシリアライズをサポートしています。

Shutdown または Close の呼び出し後に Server を再利用することは許可されなくなりました。過去には公式にサポートされておらず、しばしば驚くべき動作をしていました。サーバーのServeメソッドへの今後の呼び出しでは、シャットダウンまたは終了後はエラーが返されるようになりました。

ハンドラーが "X-Content-Type-Options"ヘッダーを "nosniff"に設定した場合、HTTPサーバーはContent-Typeを自動的に設定しません。

statusMisdirectedRequest 定数がHTTPステータスコード421に定義されました。

HTTPサーバーは、パイプライン化されたHTTP/1.1要求を受信するとき、コンテキストをキャンセルしたり、CloseNotifierチャネルを送信したりしなくなりました。ブラウザはHTTPパイプライニングを使用しませんが、(Debianの apt のような)いくつかのクライアントはそうするように設定されているかもしれません。

DefaultTransportで使用されるProxyFromEnvironmentは、CIDR表記と NO_PROXY 環境変数のポートをサポートするようになりました。

net/http/httputil

ReverseProxyには、エラーの処理方法の変更を許可するErrorHandlerオプションが追加されました。

さらに、ReverseProxyは、gRPCプロトコルの要求に従い "TE:trailers" リクエストヘッダをバックエンドに渡すようになりまさひた。

os

新しいUserCacheDir関数は、ユーザー固有のキャッシュデータに使用するデフォルトのルートディレクトリを返します。

新しいModeIrregularは、ファイルが通常のファイルではないことを表すFileModeビットです。1

Symlinkは、デベロッパーモードが有効になっているマシンで、Windows 10上の特権を持たないユーザーのために機能するようになりました。

ノンブロッキングディスクリプタが NewFile に渡されると、結果の *File は非ブロッキングモードに保持されます。これは、その *File のI/Oが別のスレッドではなくランタイムポーラーを使用し、SetDeadlineメソッドが機能することを意味します。

os/signal

新しいIgnored関数は、シグナルが現在無視されているかどうかを報告します。

os/user

os/userパッケージは、環境変数 CGO_ENABLED=0 の使用とは関係なく、buildタグ "osusergo" を使用して純粋なGoモードで構築できるようになりました。以前は、パッケージの純粋なGo実装を使用する唯一の方法は、プログラム全体でcgoサポートを無効にすることでした。

runtime

GODEBUG=tracebackancestors=N 環境変数を設定すると、goroutinesが作成されたスタックでトレースバックが拡張されます(Nは報告する祖先ゴルーチンの数を制限します)。

runtime/pprof

このリリースでは、プログラムが開始されてから割り当てられた総バイト数(ガベージコレクションバイトを含む)をプロファイルする新しい "allocs" プロファイルタイプが追加されました。これは、 -alloc_space モードで表示される既存の "heap" プロファイルと同じです。 go test -memprofile=... は "heap" プロファイルの代わりに "allocs" プロファイルをレポートします。

sync

ミューテックスプロファイルには、RWMutexに対するリーダー/ライターの競合が含まれるようになりました。ライター/ライターの競合は、すでにミューテックスプロファイルに含まれていました。

syscall

Windowsでは、いくつかのフィールドが uintptr から新しい Pointer タイプに変更され、Goのガベージコレクタでの問題を回避しました。同じ変更が golang.org/x/sys/windows パッケージに加えられました。影響を受けるコードでは、ユーザーはまずsyscallパッケージから golang.org/x/sys/windows パッケージに移行してから、 unsafe.Pointer変換ルールに従いながらポインタを使用するように変更する必要があります。

Linuxでは、Facessatのflagsパラメータはglibcと同様に実装されました。 以前のGoリリースでは、flagsパラメータは無視されました。

Linuxでは、Fchmodatflags パラメータが検証されました。 Linuxの fchmodat はflagsパラメータをサポートしていないので、glibcの動作を模倣し、ゼロ以外の場合はエラーを返します。

text/scanner

Scanner.Scanメソッドは、生の文字列リテラルのStringではなくRawStringトークンを返すようになりました。

text/template

= トークンを使用して、割り当てによってテンプレート変数を変更できるようになりました:

  {{ $v := "init" }}
  {{ if true }}
    {{ $v = "changed" }}
  {{ end }}
  v: {{ $v }} {{/* "changed" */}}

以前のバージョンでは、テンプレート関数に渡される型なしのnil値は無視されていました。それらは通常の引数として渡されます。

time

signとoffsetで示されるタイムゾーンのパースがサポートされるようになりました。以前のバージョンでは、数値のタイムゾーン名( +03 など)は有効とみなされず、タイムゾーン名が必要な場合は3文字の略語( MST など)のみが受け入れられました。


  1. 原文があいまいだったため省略 ... nothing else is known about it, or that it's not a socket, device, named pipe, symlink, or other file type for which Go has a defined mode bit.