Go 1 リリースノート
Go 1 の紹介
Go バージョン 1 (略して Go 1) は、信頼性の高い製品、プロジェクト、および出版物を作成するための安定した基盤を提供する言語と一連のコアライブラリを定義します。
Go 1 の原動力は、ユーザーにとっての安定性です。人々は Go プログラムを書き、Google App Engine のような運用環境を含め、何年もの間、変更なしにコンパイルおよび実行されることを期待できるはずです。同様に、人々は Go に関する本を書き、その本がどのバージョンの Go を記述しているかを述べることができ、そのバージョン番号がずっと後でも意味を持つことができるはずです。
Go 1 でコンパイルされるコードは、Go バージョン 1.1、1.2 などの更新やバグ修正が発行されても、ごく一部の例外を除き、そのバージョンの存続期間中、引き続きコンパイルおよび実行されるはずです。重要な修正を除いて、Go 1 の後続リリースで行われる言語およびライブラリへの変更は、機能を追加する可能性がありますが、既存の Go 1 プログラムを壊すことはありません。Go 1 互換性ドキュメントで、互換性ガイドラインが詳しく説明されています。
Go 1 は、現在の Go の姿を表しており、言語の全面的な再検討ではありません。私たちは新しい機能の設計を避け、代わりに問題と矛盾の解消、移植性の向上に注力しました。Go 言語とパッケージには、以前から検討し、プロトタイプを作成していたが、主に重大な後方非互換性があるためにリリースされていなかった多くの変更があります。Go 1 はそれらをリリースする機会であり、長期的に役立ちますが、同時に Go 1 が古いプログラムに対して非互換性を導入することも意味します。幸いなことに、go fix ツールは、プログラムを Go 1 標準に準拠させるために必要な作業の多くを自動化できます。
このドキュメントでは、既存のコードを更新するプログラマーに影響を与える Go 1 の主要な変更点を概説します。参照点は以前のリリースである r60 (r60.3 とタグ付けされています) です。また、r60 から Go 1 で実行するようにコードを更新する方法も説明します。
言語の変更点
Append
append 組み込み可変長関数は、要素をスライスの末尾に追加してスライスを簡単に拡張できるようにします。一般的な使用法は、出力を生成するときにバイトスライスの末尾にバイトを追加することです。ただし、append は、もう一つの一般的なケースである文字列を []byte に追加する方法を提供していませんでした。
greeting := []byte{}
greeting = append(greeting, []byte("hello ")...)
copy の同様の特性に倣い、Go 1 では、文字列をバイトスライスに直接 (バイト単位で) 追加できるようになり、文字列とバイトスライスの間の摩擦が軽減されます。変換はもはや必要ありません
greeting = append(greeting, "world"...)
更新: これは新機能であるため、既存のコードは変更不要です。
Close
close 組み込み関数は、送信者がこれ以上値を送信しないことを通知するメカニズムを提供します。これはチャネル上の for range ループの実装にとって重要であり、他の状況でも役立ちます。部分的には設計上、部分的にはそうでなければ発生する可能性のある競合状態のため、データを受信するゴルーチンではなく、チャネルを送信するゴルーチンのみが使用することを意図しています。しかし、Go 1 以前は、close が正しく使用されていることをコンパイル時にチェックする方法はありませんでした。
このギャップを少なくとも部分的に埋めるために、Go 1 では受信専用チャネルでの close を禁止しています。そのようなチャネルを閉じようとすると、コンパイル時エラーになります。
var c chan int
var csend chan<- int = c
var crecv <-chan int = c
close(c) // legal
close(csend) // legal
close(crecv) // illegal
更新: Go 1 以前から受信専用チャネルを閉じようとする既存のコードは誤りであり、修正する必要があります。コンパイラは現在、そのようなコードを拒否します。
複合リテラル
Go 1 では、配列、スライス、またはマップ型の複合リテラルは、要素の初期化子がポインタ型の場合、要素の型指定を省略できます。この例の 4 つの初期化はすべて有効です。最後のものは Go 1 以前は無効でした。
type Date struct {
month string
day int
}
// Struct values, fully qualified; always legal.
holiday1 := []Date{
Date{"Feb", 14},
Date{"Nov", 11},
Date{"Dec", 25},
}
// Struct values, type name elided; always legal.
holiday2 := []Date{
{"Feb", 14},
{"Nov", 11},
{"Dec", 25},
}
// Pointers, fully qualified, always legal.
holiday3 := []*Date{
&Date{"Feb", 14},
&Date{"Nov", 11},
&Date{"Dec", 25},
}
// Pointers, type name elided; legal in Go 1.
holiday4 := []*Date{
{"Feb", 14},
{"Nov", 11},
{"Dec", 25},
}
更新: この変更は既存のコードには影響しませんが、既存のソースに gofmt -s コマンドを適用すると、特に許可されている箇所では明示的な要素型が省略されます。
init 中のゴルーチン
古い言語では、初期化中に実行される go ステートメントはゴルーチンを作成するが、プログラム全体の初期化が完了するまで実行を開始しないと定義されていました。これは多くの場所でぎこちなさを生み出し、事実上 init 構造の有用性を制限しました。初期化中に別のパッケージがライブラリを使用できる場合、ライブラリはゴルーチンを避けることを余儀なくされました。この設計はシンプルさと安全性の理由から行われましたが、言語に対する私たちの自信が高まるにつれて、不必要に思えるようになりました。初期化中にゴルーチンを実行することは、通常の実行中に実行することよりも複雑でも安全でもありません。
Go 1 では、ゴルーチンを使用するコードは、デッドロックを発生させることなく init ルーチンおよびグローバル初期化式から呼び出すことができます。
var PackageGlobal int
func init() {
c := make(chan int)
go initializationFunction(c)
PackageGlobal = <-c
}
更新: これは新機能であるため、既存のコードは変更不要ですが、main の前にゴルーチンが開始しないことに依存するコードは壊れる可能性があります。標準リポジトリにはそのようなコードはありませんでした。
rune 型
言語仕様では int 型を 32 ビットまたは 64 ビット幅にすることを許可していますが、現在の実装では 64 ビットプラットフォームでも int を 32 ビットに設定しています。64 ビットプラットフォームでは int を 64 ビットにすることが望ましいでしょう。(大きなスライスのインデックス付けには重要な結果があります。) ただし、int 型は Unicode コードポイントを保持するためにも使用されていたため、古い言語で Unicode 文字を処理する場合、この変更はスペースを浪費します。int が 32 ビットから 64 ビットに増加すると、各コードポイントは追加の 32 ビットのストレージを浪費します。
64 ビット int への変更を可能にするために、Go 1 では個々の Unicode コードポイントを表す新しい基本型 rune を導入します。これは int32 のエイリアスであり、byte が uint8 のエイリアスであることと同様です。
'a'、'語'、'\u0345' などの文字リテラルは、1.0 がデフォルト型 float64 を持つことと同様に、デフォルト型 rune を持つようになりました。したがって、文字定数で初期化された変数は、特に指定がない限り rune 型になります。
ライブラリは、適切な場合に int ではなく rune を使用するように更新されました。たとえば、unicode.ToLower 関数とその関連関数は現在、rune を引数にとり、rune を返します。
delta := 'δ' // delta has type rune.
var DELTA rune
DELTA = unicode.ToUpper(delta)
epsilon := unicode.ToLower(DELTA + 1)
if epsilon != 'δ'+1 {
log.Fatal("inconsistent casing for Greek")
}
更新: ほとんどのソースコードは、:= 初期化子からの型推論が新しい型を暗黙的に導入し、そこから伝播するため、この影響を受けません。一部のコードでは、単純な変換で解決できる型エラーが発生する可能性があります。
error 型
Go 1 は、以下の定義を持つ新しい組み込み型 error を導入します
type error interface {
Error() string
}
この型の結果はすべてパッケージライブラリにあるため、これについては下記で説明します。
マップからの削除
古い言語では、マップ m からキー k を持つエントリを削除するには、次のように記述しました。
m[k] = value, false
この構文は特異な特殊ケースであり、唯一の 2 対 1 の代入でした。評価されるが破棄される値 (通常は無視される) と、ほぼ常に定数 false であるブール値を渡す必要がありました。それは目的を果たしましたが、奇妙で論争の的でした。
Go 1 では、その構文はなくなりました。代わりに、新しい組み込み関数 delete があります。呼び出し
delete(m, k)
は、式 m[k] によって取得されるマップエントリを削除します。戻り値はありません。存在しないエントリを削除しても、何も行われません。
更新: go fix を実行すると、無視される値をプログラムから安全に破棄でき、false が定義済みのブール定数を指すことが明確な場合、m[k] = value, false の形式の式が delete(m, k) に変換されます。fix ツールは、構文の他の使用箇所をプログラマーによる検査のためにフラグ付けします。
マップのイテレーション
古い言語仕様では、マップのイテレーション順序を定義していなかったため、実際にはハードウェアプラットフォーム間で異なっていました。これにより、マップをイテレーションするテストが脆弱で移植性がなくなり、あるマシンでは常に合格するが別のマシンでは失敗するという不快な特性がありました。
Go 1 では、for range ステートメントを使用してマップをイテレーションする際に要素が訪問される順序は、同じループが同じマップで複数回実行されたとしても、予測不可能であると定義されています。コードは、要素が特定の順序で訪問されると仮定すべきではありません。
この変更は、イテレーション順序に依存するコードが早期に壊れ、問題になるずっと前に修正される可能性が高いことを意味します。同様に重要なこととして、これにより、プログラムが範囲ループを使用してマップから要素を選択している場合でも、マップの実装がより良いマップバランスを確保できるようになります。
m := map[string]int{"Sunday": 0, "Monday": 1}
for name, value := range m {
// This loop should not assume Sunday will be visited first.
f(name, value)
}
更新: これはツールでは解決できない変更です。ほとんどの既存のコードは影響を受けませんが、一部のプログラムは壊れたり誤動作したりする可能性があります。マップ上のすべての range ステートメントを手動で確認し、イテレーション順序に依存していないことを確認することをお勧めします。標準リポジトリにはそのような例がいくつかありましたが、修正されています。イテレーション順序に依存することは、すでに誤りであり、未指定であったことに注意してください。この変更は予測不能性を明文化したものです。
多重代入
言語仕様では、代入において右辺の式がすべて評価されてから、左辺の式が代入されることが長い間保証されてきました。予測可能な動作を保証するために、Go 1 は仕様をさらに洗練しています。
代入文の左辺に、関数呼び出しや配列インデックス操作などの評価を必要とする式が含まれている場合、これらはすべて、値が変数に代入される前に、通常の左から右へのルールに従って実行されます。すべてが評価されると、実際の代入は左から右の順に進みます。
これらの例は動作を示しています。
sa := []int{1, 2, 3}
i := 0
i, sa[i] = 1, 2 // sets i = 1, sa[0] = 2
sb := []int{1, 2, 3}
j := 0
sb[j], j = 2, 1 // sets sb[0] = 2, j = 1
sc := []int{1, 2, 3}
sc[0], sc[0] = 1, 2 // sets sc[0] = 1, then sc[0] = 2 (so sc[0] = 2 at end)
更新: これはツールでは解決できない変更ですが、破損の可能性は低いです。この変更によって標準リポジトリ内のコードは壊れておらず、以前の未指定の動作に依存するコードはすでに誤っていました。
戻り値とシャドウ変数
よくある間違いは、結果変数と同じ名前だが同じ変数ではない変数への代入の後に、return (引数なし) を使用することです。この状況は「シャドウイング」と呼ばれます。結果変数は、内側のスコープで宣言された同じ名前の別の変数によってシャドウされています。
名前付き戻り値を持つ関数では、Go 1 コンパイラは、名前付き戻り値のいずれかが return ステートメントの時点でシャドウされている場合、引数なしの return ステートメントを許可しません。(これは仕様の一部ではありません。この領域はまだ調査中だからです。この状況は、コンパイラが明示的な return ステートメントで終わらない関数を拒否することに似ています。)
この関数はシャドウされた戻り値を暗黙的に返し、コンパイラによって拒否されます
func Bug() (i, j, k int) {
for i = 0; i < 5; i++ {
for j := 0; j < 5; j++ { // Redeclares j.
k += i * j
if k > 100 {
return // Rejected: j is shadowed here.
}
}
}
return // OK: j is not shadowed here.
}
更新: このように戻り値をシャドウするコードはコンパイラによって拒否され、手動で修正する必要があります。標準リポジトリで発生した少数のケースは、ほとんどがバグでした。
エクスポートされていないフィールドを持つ構造体のコピー
古い言語では、異なるパッケージに属するエクスポートされていないフィールドを含む構造体値のコピーをパッケージが作成することを許可していませんでした。ただし、メソッドレシーバーについては必須の例外がありました。また、copy と append の実装は、この制限を尊重していませんでした。
Go 1 では、パッケージが他のパッケージからエクスポートされていないフィールドを含む構造体値をコピーできるようになります。この変更は、矛盾を解決するだけでなく、新しい種類の API を可能にします。パッケージは、ポインタやインターフェースに頼ることなく、不透明な値を返すことができます。time.Time と reflect.Value の新しい実装は、この新しいプロパティを利用する型の例です。
例として、パッケージ p に次の定義が含まれている場合、
type Struct struct {
Public int
secret int
}
func NewStruct(a int) Struct { // Note: not a pointer.
return Struct{a, f(a)}
}
func (s Struct) String() string {
return fmt.Sprintf("{%d (secret %d)}", s.Public, s.secret)
}
p をインポートするパッケージは、p.Struct 型の値を自由に代入およびコピーできます。内部では、エクスポートされていないフィールドは、エクスポートされているかのように代入およびコピーされますが、クライアントコードはそれらを認識することはありません。コード
import "p"
myStruct := p.NewStruct(23)
copyOfMyStruct := myStruct
fmt.Println(myStruct, copyOfMyStruct)
は、構造体の秘密フィールドが新しい値にコピーされたことを示します。
更新: これは新機能であるため、既存のコードは変更不要です。
同等性
Go 1 以前は、言語では構造体と配列の値に対する等価性を定義していませんでした。これは、特に、構造体と配列をマップのキーとして使用できないことを意味しました。一方、Go は関数とマップの値に対する等価性を定義していました。関数等価性はクロージャの存在下で問題がありました (2 つのクロージャがいつ等しいのか?)。一方、マップ等価性はポインタを比較し、マップの内容を比較していませんでした。これは通常、ユーザーが望むものではありませんでした。
Go 1 はこれらの問題に対処しました。まず、構造体と配列は等価性 (== および !=) を比較でき、したがって、等価性も定義されている要素から構成されている場合、要素ごとの比較を使用してマップキーとして使用できます。
type Day struct {
long string
short string
}
Christmas := Day{"Christmas", "XMas"}
Thanksgiving := Day{"Thanksgiving", "Turkey"}
holiday := map[Day]bool{
Christmas: true,
Thanksgiving: true,
}
fmt.Printf("Christmas is a holiday: %t\n", holiday[Christmas])
次に、Go 1 は、nil との比較を除き、関数値の等価性の定義を削除します。最後に、マップの等価性も、nil との比較を除き、なくなりました。
スライスについては、一般的に計算が実現不可能であるため、等価性は依然として未定義であることに注意してください。また、構造体と配列については、順序比較演算子 (< < = > >=) は依然として未定義であることにも注意してください。
更新: 構造体と配列の等価性は新機能であるため、既存のコードは変更不要です。関数またはマップの等価性に依存する既存のコードはコンパイラによって拒否され、手動で修正する必要があります。影響を受けるプログラムは少ないですが、修正には再設計が必要になる場合があります。
パッケージ階層
Go 1 は、古い標準ライブラリの多くの欠陥に対処し、いくつかのパッケージを整理し、それらをより内部的に一貫性があり、移植性のあるものにしました。
このセクションでは、Go 1 でパッケージがどのように再配置されたかを説明します。一部は移動され、一部は名前が変更され、一部は削除されました。新しいパッケージについては、後のセクションで説明します。
パッケージ階層
Go 1 には、関連する項目をサブディレクトリにグループ化する再配置されたパッケージ階層があります。たとえば、utf8 と utf16 は現在 unicode のサブディレクトリにあります。また、一部のパッケージは code.google.com/p/go のサブリポジトリに移動し、その他は完全に削除されました。
| 旧パス | 新パス |
|---|---|
| asn1 | encoding/asn1 |
| csv | encoding/csv |
| gob | encoding/gob |
| json | encoding/json |
| xml | encoding/xml |
| exp/template/html | html/template |
| big | math/big |
| cmath | math/cmplx |
| rand | math/rand |
| http | net/http |
| http/cgi | net/http/cgi |
| http/fcgi | net/http/fcgi |
| http/httptest | net/http/httptest |
| http/pprof | net/http/pprof |
| net/mail | |
| rpc | net/rpc |
| rpc/jsonrpc | net/rpc/jsonrpc |
| smtp | net/smtp |
| url | net/url |
| exec | os/exec |
| scanner | text/scanner |
| tabwriter | text/tabwriter |
| template | text/template |
| template/parse | text/template/parse |
| utf8 | unicode/utf8 |
| utf16 | unicode/utf16 |
古い cmath と exp/template/html パッケージのパッケージ名は、それぞれ cmplx と template に変更されたことに注意してください。
更新: go fix を実行すると、標準リポジトリに残っているパッケージのすべてのインポートとパッケージの変更が更新されます。標準リポジトリに存在しないパッケージをインポートするプログラムは、手動で編集する必要があります。
パッケージツリー exp
exp ディレクトリ以下のパッケージは標準化されていないため、標準の Go 1 リリースディストリビューションでは利用できませんが、使用を希望する開発者向けにリポジトリでソースコード形式で利用できます。
Go 1 のリリース時に、いくつかのパッケージが exp 以下に移動しました
ebnfhtml†go/types
(†EscapeString および UnescapeString 型は引き続きパッケージ html に存在します。)
これらすべてのパッケージは、同じ名前で exp/ 接頭辞付きで利用できます: exp/ebnf など。
また、utf8.String 型は独自のパッケージ exp/utf8string に移動されました。
最後に、gotype コマンドは exp/gotype に移動し、ebnflint は exp/ebnflint に移動しました。インストールされている場合、それらは $GOROOT/bin/tool にあります。
更新: exp のパッケージを使用するコードは手動で更新するか、exp が利用可能なインストールからコンパイルする必要があります。go fix ツールまたはコンパイラは、そのような使用法について苦情を言います。
パッケージツリー old
非推奨のため、old ディレクトリ以下のパッケージは標準の Go 1 リリースディストリビューションでは利用できませんが、使用を希望する開発者向けにソースコード形式で利用できます。
新しい場所にあるパッケージは
old/netchan
更新: 現在 old にあるパッケージを使用するコードは、手動で更新するか、old が利用可能なインストールからコンパイルする必要があります。go fix ツールは、そのような使用法について警告します。
削除されたパッケージ
Go 1 ではいくつかのパッケージを完全に削除します
container/vectorexp/datafmtgo/typecheckerold/regexpold/templatetry
およびコマンド gotry も削除されます。
更新: container/vector を使用するコードは、直接スライスを使用するように更新する必要があります。Go 言語コミュニティ Wiki を参照して、いくつかの提案を確認してください。他のパッケージを使用するコード (ほとんどないはずです) は再考する必要があります。
サブリポジトリに移動するパッケージ
Go 1 では、多くのパッケージが他のリポジトリ、通常はメイン Go リポジトリのサブリポジトリに移動しました。この表に、古いインポートパスと新しいインポートパスを示します。
| 旧 | 新 |
|---|---|
| crypto/bcrypt | code.google.com/p/go.crypto/bcrypt |
| crypto/blowfish | code.google.com/p/go.crypto/blowfish |
| crypto/cast5 | code.google.com/p/go.crypto/cast5 |
| crypto/md4 | code.google.com/p/go.crypto/md4 |
| crypto/ocsp | code.google.com/p/go.crypto/ocsp |
| crypto/openpgp | code.google.com/p/go.crypto/openpgp |
| crypto/openpgp/armor | code.google.com/p/go.crypto/openpgp/armor |
| crypto/openpgp/elgamal | code.google.com/p/go.crypto/openpgp/elgamal |
| crypto/openpgp/errors | code.google.com/p/go.crypto/openpgp/errors |
| crypto/openpgp/packet | code.google.com/p/go.crypto/openpgp/packet |
| crypto/openpgp/s2k | code.google.com/p/go.crypto/openpgp/s2k |
| crypto/ripemd160 | code.google.com/p/go.crypto/ripemd160 |
| crypto/twofish | code.google.com/p/go.crypto/twofish |
| crypto/xtea | code.google.com/p/go.crypto/xtea |
| exp/ssh | code.google.com/p/go.crypto/ssh |
| image/bmp | code.google.com/p/go.image/bmp |
| image/tiff | code.google.com/p/go.image/tiff |
| net/dict | code.google.com/p/go.net/dict |
| net/websocket | code.google.com/p/go.net/websocket |
| exp/spdy | code.google.com/p/go.net/spdy |
| encoding/git85 | code.google.com/p/go.codereview/git85 |
| patch | code.google.com/p/go.codereview/patch |
| exp/wingui | code.google.com/p/gowingui |
更新: go fix を実行すると、これらのパッケージのインポートが新しいインポートパスを使用するように更新されます。これらのパッケージに依存するインストールは、go get コマンドを使用してそれらをインストールする必要があります。
ライブラリの主な変更点
このセクションでは、コアライブラリへの重要な変更点、つまり最も多くのプログラムに影響する変更点について説明します。
error 型と errors パッケージ
os.Error が os パッケージに配置されているのは、ほとんどが歴史的な理由によるものです。エラーは最初に os パッケージの実装時に発生し、当時はシステム関連に見えました。それ以来、エラーはオペレーティングシステムよりも基本的なものであることが明らかになりました。たとえば、syscall のように os が依存するパッケージで Errors を使用できると便利です。また、os に Error があると、そうでなければ存在しない多くの os への依存関係が生じます。
Go 1 は、組み込みの error インターフェース型と、ユーティリティ関数を含む別の errors パッケージ (bytes および strings に類似) を導入することで、これらの問題を解決します。os.NewError をerrors.New に置き換え、エラーに環境内でより中心的な場所を与えます。
広く使用されている String メソッドが error インターフェースの偶発的な満足を引き起こさないように、error インターフェースは、そのメソッドに代わりに Error という名前を使用します。
type error interface {
Error() string
}
fmt ライブラリは、エラー値を簡単に表示できるように、String に対してすでに行っているように、Error を自動的に呼び出します。
type SyntaxError struct {
File string
Line int
Message string
}
func (se *SyntaxError) Error() string {
return fmt.Sprintf("%s:%d: %s", se.File, se.Line, se.Message)
}
すべての標準パッケージは、新しいインターフェースを使用するように更新されました。古い os.Error はなくなりました。
新しいパッケージerrorsには、関数が含まれています。
func New(text string) error
文字列をエラーに変換します。これは古い os.NewError を置き換えます。
var ErrSyntax = errors.New("syntax error")
更新: go fix を実行すると、変更の影響を受けるほとんどすべてのコードが更新されます。String メソッドを持つエラー型を定義するコードは、メソッド名を Error に変更するために手動で更新する必要があります。
システムコールエラー
os.Error (およびその他すべて) より以前の古い syscall パッケージは、エラーを int 値として返していました。次に、os パッケージは、EINVAL などの多くのエラーを転送しましたが、プラットフォームごとに異なるエラーセットを使用していました。この動作は不快で移植性がありませんでした。
Go 1 では、syscall パッケージは代わりにシステムコールエラーに対して error を返します。Unix では、実装は error を満たし、古い os.Errno を置き換えるsyscall.Errno 型によって行われます。
os.EINVAL と関連する変更については別の場所で説明されています。
更新: go fix を実行すると、変更の影響を受けるほとんどすべてのコードが更新されます。いずれにしても、ほとんどのコードは syscall ではなく os パッケージを使用すべきであり、そのため影響を受けません。
時間
プログラミング言語で時間を適切にサポートすることは常に課題です。古い Go の time パッケージは int64 単位で、実際の型安全性はなく、絶対時間と期間の区別がありませんでした。
Go 1 ライブラリにおける最も広範な変更の 1 つは、したがって、time パッケージの完全な再設計です。int64 としてのナノ秒の整数値と、時間や年などの人間単位を扱うための個別の *time.Time 型の代わりに、現在 2 つの基本的な型があります。時間の瞬間を表すtime.Time (値なので * はなくなりました) と、間隔を表すtime.Duration です。どちらもナノ秒の解像度を持っています。Time は古代の過去から遠い未来までの任意の時間を表すことができますが、Duration は約 290 年間のプラスマイナスしかまたがることができません。これらの型にはメソッドがあり、さらに time.Second などの役立つ事前定義された定数期間が多数あります。
新しいメソッドには、Duration を Time に追加するTime.Add や、2 つの Times を減算して Duration を生成するTime.Sub などがあります。
最も重要な意味論的変更は、Unix エポック (1970 年 1 月 1 日) が、Unix を言及する関数とメソッド (Time 型のtime.Unix とUnix およびUnixNano メソッド) にのみ関連するようになったことです。特に、time.Now は、古い API のように Unix エポックからのナノ秒数ではなく、time.Time 値を返します。
// sleepUntil sleeps until the specified time. It returns immediately if it's too late. func sleepUntil(wakeup time.Time) { now := time.Now() // A Time. if !wakeup.After(now) { return } delta := wakeup.Sub(now) // A Duration. fmt.Printf("Sleeping for %.3fs\n", delta.Seconds()) time.Sleep(delta) }
新しい型、メソッド、定数は、os やファイルタイムスタンプの表現など、時間を使用するすべての標準パッケージに伝播されています。
更新: go fix ツールは、古い time パッケージの多くの使用箇所を新しい型とメソッドを使用するように更新しますが、秒あたりのナノ秒を表す 1e9 などの値は置き換えません。また、一部の値の型変更により、fix ツールによって書き換えられた式の一部は、さらに手動で編集する必要がある場合があります。そのような場合、書き換えには古い機能の正しい関数またはメソッドが含まれますが、型が間違っているか、さらに分析が必要な場合があります。
ライブラリの軽微な変更
このセクションでは、あまり一般的に使用されないパッケージへの変更や、go fix を実行する必要がある以外の少数のプログラムに影響する変更など、より小さな変更について説明します。このカテゴリには、Go 1 で新しいパッケージが含まれます。これらはまとめて移植性を向上させ、動作を正規化し、インターフェースをよりモダンで Go らしいものにします。
archive/zip パッケージ
Go 1 では、*zip.Writer に Write メソッドがなくなりました。その存在は間違いでした。
更新: 影響を受けるわずかなコードはコンパイラによって捕捉され、手動で更新する必要があります。
bufio パッケージ
Go 1 では、bufio.NewReaderSize および bufio.NewWriterSize 関数は、無効なサイズに対してエラーを返さなくなりました。引数サイズが小さすぎるか無効な場合、調整されます。
更新: go fix を実行すると、エラーを _ に代入する呼び出しが更新されます。修正されていない呼び出しはコンパイラによって捕捉され、手動で更新する必要があります。
compress/flate、compress/gzip、および compress/zlib パッケージ
Go 1 では、compress/flate、compress/gzip、および compress/zlib の NewWriterXxx 関数はすべて、圧縮レベルを受け取る場合は (*Writer, error) を返し、それ以外の場合は *Writer を返します。パッケージ gzip の Compressor および Decompressor 型は Writer および Reader に名前が変更されました。パッケージ flate の WrongValueError 型は削除されました。
更新 go fix を実行すると、古い名前と、エラーを _ に代入する呼び出しが更新されます。修正されていない呼び出しはコンパイラによって捕捉され、手動で更新する必要があります。
crypto/aes および crypto/des パッケージ
Go 1 では、Reset メソッドが削除されました。Go はメモリがコピーされないことを保証しないため、このメソッドは誤解を招くものでした。
暗号固有の型 *aes.Cipher、*des.Cipher、および *des.TripleDESCipher は、cipher.Block を優先して削除されました。
更新: Reset への呼び出しを削除します。特定の暗号型の使用箇所を cipher.Block に置き換えます。
crypto/elliptic パッケージ
Go 1 では、elliptic.Curve がインターフェースになり、代替実装が可能になりました。曲線パラメーターはelliptic.CurveParams 構造体に移動されました。
更新: 既存の *elliptic.Curve のユーザーは、単に elliptic.Curve に変更する必要があります。Marshal、Unmarshal、および GenerateKey への呼び出しは、現在 crypto/elliptic の関数であり、最初の引数として elliptic.Curve を受け取ります。
crypto/hmac パッケージ
Go 1 では、hmac.NewMD5 などのハッシュ固有の関数が crypto/hmac から削除されました。代わりに、hmac.New は md5.New などの hash.Hash を返す関数を受け取ります。
更新: go fix を実行すると、必要な変更が実行されます。
crypto/x509 パッケージ
Go 1 では、crypto/x509 のCreateCertificate 関数とCreateCRL メソッドは、以前は *rsa.PublicKey または *rsa.PrivateKey を受け取っていた場所に interface{} を受け取るように変更されました。これにより、将来的に他の公開鍵アルゴリズムを実装できるようになります。
更新: 変更は不要です。
encoding/binary パッケージ
Go 1 では、binary.TotalSize 関数は、reflect.Value ではなく interface{} 引数を受け取るSize に置き換えられました。
更新: 影響を受けるわずかなコードはコンパイラによって捕捉され、手動で更新する必要があります。
encoding/xml パッケージ
Go 1 では、xml パッケージは、encoding/gob などの他のマーシャリングパッケージに近いデザインになりました。
古い Parser 型はDecoder に名前が変更され、新しいDecode メソッドが追加されました。Encoder 型も導入されました。
Marshal および Unmarshal 関数は、現在 []byte 値で動作します。ストリームで動作させるには、新しいEncoder および Decoder 型を使用してください。
値をマーシャリングまたはアンマーシャリングする場合、フィールドタグでサポートされるフラグの形式がjson パッケージに近づくように変更されました (`xml:"name,flag"`)。フィールドタグ、フィールド名、および XML 属性名と要素名の間で行われる照合は、現在大文字と小文字を区別します。XMLName フィールドタグが存在する場合、マーシャリングされる XML 要素の名前とも一致する必要があります。
更新: go fix を実行すると、Unmarshal の一部の呼び出しを除き、パッケージのほとんどの使用箇所が更新されます。フィールドタグには特別な注意が必要です。fix ツールはそれらを更新せず、手動で修正しないと、場合によってはサイレントに誤動作するためです。たとえば、古い "attr" は現在 ",attr" と記述されますが、プレーンな "attr" は有効なままですが、意味が異なります。
expvar パッケージ
Go 1 では、RemoveAll 関数が削除されました。Iter 関数と *Map の Iter メソッドは、Do と (*Map).Do に置き換えられました。
更新: expvar を使用するほとんどのコードは変更不要です。Iter を使用していたまれなコードは、同じ効果を得るためにクロージャを Do に渡すように更新できます。
flag パッケージ
Go 1 では、インターフェースflag.Valueが少し変更されました。Set メソッドは、成功または失敗を示すために bool ではなく error を返すようになりました。
また、時間間隔を指定する引数値をサポートするための新しい種類のフラグ Duration があります。そのようなフラグの値は、time.Duration がフォーマットするのと同様に、単位を指定する必要があります: 10s, 1h30m など。
var timeout = flag.Duration("timeout", 30*time.Second, "how long to wait for completion")
更新: 独自のフラグを実装するプログラムは、Set メソッドを更新するために軽微な手動修正が必要です。Duration フラグは新機能であり、既存のコードには影響しません。
go/* パッケージ
go 以下のいくつかのパッケージの API がわずかに改訂されました。
go/scanner、go/parser、go/printer、および go/doc パッケージに、構成モードフラグの具体的な Mode 型が導入されました。
AllowIllegalChars と InsertSemis モードはgo/scanner パッケージから削除されました。これらは Go ソースファイル以外のテキストをスキャンするのに主に役立ちました。代わりに、その目的にはtext/scanner パッケージを使用する必要があります。
スキャナのInit メソッドに提供されるErrorHandler は、インターフェースではなく、単なる関数になりました。ErrorVector 型は (既存の)ErrorList 型を優先して削除され、ErrorVector メソッドは移行されました。スキャナのクライアントに ErrorVector を埋め込む代わりに、クライアントは ErrorList を維持する必要があります。
go/parser パッケージによって提供される解析関数セットは、主要な解析関数ParseFile と、いくつかの便利な関数ParseDir およびParseExpr に縮小されました。
go/printer パッケージは、追加の構成モードSourcePos をサポートしています。設定すると、プリンタは //line コメントを出力し、生成された出力に元のソースコードの位置情報が含まれるようになります。新しい型CommentedNode は、任意のast.Node に関連付けられたコメントを提供するために使用できます (これまではast.File のみがコメント情報を持っていました)。
go/doc パッケージの型名は、Doc サフィックスを削除することで簡素化されました: PackageDoc は Package に、ValueDoc は Value になど。また、すべての型は一貫して Name フィールド (または Value 型の場合は Names) を持ち、Type.Factories は Type.Funcs になりました。doc.NewPackageDoc(pkg, importpath) を呼び出す代わりに、パッケージのドキュメントは次のように作成されます。
doc.New(pkg, importpath, mode)
ここで、新しい mode パラメータは操作モードを指定します。AllDecls に設定すると、すべての宣言 (エクスポートされたものだけでなく) が考慮されます。関数 NewFileDoc は削除され、関数 CommentText はast.CommentGroup のメソッドText になりました。
パッケージgo/tokenでは、token.FileSetメソッドFiles(もともとは*token.Fileのチャネルを返していた)が、代わりに関数引数を受け取るイテレータIterateに置き換えられました。
パッケージgo/buildでは、APIがほぼ完全に置き換えられました。このパッケージはGoパッケージ情報を計算しますが、ビルドは実行しません。CmdとScript型はなくなりました。(コードをビルドするには、新しいgoコマンドを使用してください。) DirInfo型は現在Packageと命名されています。FindTreeとScanDirはImportとImportDirに置き換えられました。
更新: go のパッケージを使用するコードは手動で更新する必要があります。コンパイラは不正な使用法を拒否します。go/doc 型のいずれかと組み合わせて使用されるテンプレートは、手動での修正が必要になる場合があります。名前が変更されたフィールドはランタイムエラーにつながります。
hash パッケージ
Go 1 では、hash.Hash の定義に新しいメソッド BlockSize が含まれています。この新しいメソッドは主に暗号化ライブラリで使用されます。
hash.Hash インターフェースの Sum メソッドは、ハッシュ値が追加される []byte 引数を取るようになりました。以前の動作は、呼び出しに nil 引数を追加することで再現できます。
更新: 既存の hash.Hash の実装は、BlockSize メソッドを追加する必要があります。入力データを 1 バイトずつ処理するハッシュは、BlockSize を実装して 1 を返すことができます。go fix を実行すると、hash.Hash のさまざまな実装の Sum メソッドへの呼び出しが更新されます。
更新: パッケージの機能は新しいため、更新は不要です。
http パッケージ
Go 1 ではhttpパッケージがリファクタリングされ、一部のユーティリティがhttputilサブディレクトリに配置されました。これらの要素はHTTPクライアントではめったに必要とされません。影響を受ける項目は次のとおりです。
- ClientConn
- DumpRequest
- DumpRequestOut
- DumpResponse
- NewChunkedReader
- NewChunkedWriter
- NewClientConn
- NewProxyClientConn
- NewServerConn
- NewSingleHostReverseProxy
- ReverseProxy
- ServerConn
Request.RawURL フィールドは削除されました。これは歴史的な遺物でした。
Handle および HandleFunc 関数、および ServeMux の同様の名前のメソッドは、同じパターンを 2 回登録しようとするとパニックするようになりました。
更新: go fix を実行すると、影響を受ける少数のプログラムが更新されますが、RawURL の使用箇所は手動で修正する必要があります。
image パッケージ
image パッケージには、いくつかの小さな変更、再配置、および名前変更がありました。
色処理コードのほとんどは、独自のパッケージimage/colorに移動されました。移動した要素については対称性が生じます。例えば、image.RGBAの各ピクセルはcolor.RGBAです。
古い image/ycbcr パッケージは、一部の名前変更とともに、image および image/color パッケージに統合されました。
古い image.ColorImage 型は引き続き image パッケージに存在しますが、image.Uniform に名前が変更され、image.Tiled は削除されました。
この表に名前変更をリストします。
| 旧 | 新 |
|---|---|
| image.Color | color.Color |
| image.ColorModel | color.Model |
| image.ColorModelFunc | color.ModelFunc |
| image.PalettedColorModel | color.Palette |
| image.RGBAColor | color.RGBA |
| image.RGBA64Color | color.RGBA64 |
| image.NRGBAColor | color.NRGBA |
| image.NRGBA64Color | color.NRGBA64 |
| image.AlphaColor | color.Alpha |
| image.Alpha16Color | color.Alpha16 |
| image.GrayColor | color.Gray |
| image.Gray16Color | color.Gray16 |
| image.RGBAColorModel | color.RGBAModel |
| image.RGBA64ColorModel | color.RGBA64Model |
| image.NRGBAColorModel | color.NRGBAModel |
| image.NRGBA64ColorModel | color.NRGBA64Model |
| image.AlphaColorModel | color.AlphaModel |
| image.Alpha16ColorModel | color.Alpha16Model |
| image.GrayColorModel | color.GrayModel |
| image.Gray16ColorModel | color.Gray16Model |
| ycbcr.RGBToYCbCr | color.RGBToYCbCr |
| ycbcr.YCbCrToRGB | color.YCbCrToRGB |
| ycbcr.YCbCrColorModel | color.YCbCrModel |
| ycbcr.YCbCrColor | color.YCbCr |
| ycbcr.YCbCr | image.YCbCr |
| ycbcr.SubsampleRatio444 | image.YCbCrSubsampleRatio444 |
| ycbcr.SubsampleRatio422 | image.YCbCrSubsampleRatio422 |
| ycbcr.SubsampleRatio420 | image.YCbCrSubsampleRatio420 |
| image.ColorImage | image.Uniform |
image パッケージの New 関数 (NewRGBA、NewRGBA64 など) は、4 つの整数ではなくimage.Rectangle を引数として受け取ります。
最後に、新しい事前定義された color.Color 変数color.Black、color.White、color.Opaque、およびcolor.Transparentがあります。
更新: go fix を実行すると、変更の影響を受けるほとんどすべてのコードが更新されます。
log/syslog パッケージ
Go 1 では、syslog.NewLogger 関数は、log.Logger とともにエラーを返します。
更新: 影響を受けるわずかなコードはコンパイラによって捕捉され、手動で更新する必要があります。
mime パッケージ
Go 1 では、mime パッケージのFormatMediaType関数がParseMediaTypeと整合するように簡素化されました。現在は"text"と"html"ではなく"text/html"を受け取ります。
更新: 影響を受けるわずかなコードはコンパイラによって捕捉され、手動で更新する必要があります。
net パッケージ
Go 1 では、さまざまな SetTimeout、SetReadTimeout、および SetWriteTimeout メソッドが、それぞれSetDeadline、SetReadDeadline、およびSetWriteDeadlineに置き換えられました。接続上のアクティビティに適用されるナノ秒単位のタイムアウト値を受け取る代わりに、新しいメソッドは絶対的な期限 (time.Time 値として) を設定し、それを過ぎると読み取りと書き込みがタイムアウトし、ブロックしなくなります。
また、ネットワークアドレスへのダイヤルタイムアウトを簡素化する新しい関数net.DialTimeoutと、複数のリスナー間でマルチキャスト UDP を同時にリッスンできるようにするnet.ListenMulticastUDPがあります。net.ListenMulticastUDP 関数は、古い JoinGroup および LeaveGroup メソッドを置き換えます。
更新: 古いメソッドを使用するコードはコンパイルに失敗し、手動で更新する必要があります。意味論的な変更により、fix ツールによる自動更新は困難です。
os パッケージ
Time 関数は削除されました。呼び出し元は time パッケージのTime 型を使用する必要があります。
Exec 関数は削除されました。呼び出し元は、利用可能な場合は syscall パッケージの Exec を使用する必要があります。
ShellExpand 関数はExpandEnv に名前が変更されました。
NewFile 関数は、int ではなく uintptr fd を受け取るようになりました。ファイルのFd メソッドも uintptr を返すようになりました。
os パッケージには、基になるオペレーティングシステムによって値のセットが異なっていたため、EINVAL のようなエラー定数はなくなりました。一般的なエラープロパティをテストするためのIsPermissionのような新しい移植可能な関数と、ErrPermissionやErrNotExistのような Go らしい名前を持ついくつかの新しいエラー値があります。
Getenverror 関数は削除されました。存在しない環境変数と空の文字列を区別するには、os.Environ またはsyscall.Getenv を使用します。
Process.Wait メソッドはオプション引数を廃止し、関連する定数はパッケージから削除されました。また、関数 Wait もなくなりました。Process 型のメソッドのみが残っています。
Process.Wait が返す Waitmsg 型は、プロセスの情報を回復するためのアクセサメソッドを持つ、より移植性のあるProcessState 型に置き換えられました。Wait の変更により、ProcessState 値は常に終了したプロセスを記述します。移植性の懸念からインターフェースは他の方法でも簡素化されましたが、ProcessState.Sys およびProcessState.SysUsage メソッドが返す値は、Unix のsyscall.WaitStatus やsyscall.Rusage のような基になるシステム固有のデータ構造に型アサーションできます。
更新: go fix を実行すると、Process.Wait へのゼロ引数が削除されます。その他の変更はすべてコンパイラによって捕捉され、手動で更新する必要があります。
os.FileInfo 型
Go 1 はos.FileInfo 型を再定義し、構造体からインターフェースに変更しました。
type FileInfo interface {
Name() string // base name of the file
Size() int64 // length in bytes
Mode() FileMode // file mode bits
ModTime() time.Time // modification time
IsDir() bool // abbreviation for Mode().IsDir()
Sys() interface{} // underlying data source (can return nil)
}
ファイルモード情報は、IsDir、Perm、および String メソッドを持つ単純な整数型であるos.FileMode と呼ばれるサブタイプに移動されました。
ファイルモードのシステム固有の詳細と、(Unix の) i-number などのプロパティは、FileInfo から完全に削除されました。代わりに、各オペレーティングシステムの os パッケージは FileInfo インターフェースの実装を提供し、これにはファイルメタデータのシステム固有の表現を返す Sys メソッドがあります。たとえば、Unix システム上のファイルの i-number を検出するには、FileInfo を次のようにアンパックします。
fi, err := os.Stat("hello.go")
if err != nil {
log.Fatal(err)
}
// Check that it's a Unix file.
unixStat, ok := fi.Sys().(*syscall.Stat_t)
if !ok {
log.Fatal("hello.go: not a Unix file")
}
fmt.Printf("file i-number: %d\n", unixStat.Ino)
"hello.go" が Unix ファイルであると仮定すると (これは賢明ではありませんが)、i-number 式は次のように短縮できます。
fi.Sys().(*syscall.Stat_t).Ino
FileInfo の使用の大部分は、標準インターフェースのメソッドのみを必要とします。
os パッケージには、もはや ENOENT のような POSIX エラーのラッパーは含まれていません。値のセットが基になるオペレーティングシステムによって異なっていたためです。特定の特定のエラー条件を検証する必要がある少数のプログラムのために、現在、IsExist、IsNotExist、およびIsPermissionというブール関数があります。
f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
if os.IsExist(err) {
log.Printf("%s already exists", name)
}
更新: go fix を実行すると、現在の os.FileInfo および os.FileMode API の古い同等物を使用するコードが更新されます。システム固有のファイルの詳細が必要なコードは、手動で更新する必要があります。os パッケージの古い POSIX エラー値を使用するコードはコンパイルに失敗し、これも手動で更新する必要があります。
os/signal パッケージ
Go 1 の os/signal パッケージは、すべての着信シグナルを受信するチャネルを返していた Incoming 関数を、既存のチャネルに特定のシグナルの配信を要求する選択的な Notify 関数に置き換えます。
更新: コードは手動で更新する必要があります。文字通りの翻訳
c := signal.Incoming()
は
c := make(chan os.Signal, 1)
signal.Notify(c) // ask for all signals
ですが、ほとんどのコードは代わりに処理したい特定の信号をリストする必要があります。
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT)
path/filepath パッケージ
Go 1 では、path/filepath パッケージのWalk関数は、Visitorインターフェース値ではなく、WalkFunc型の関数値を受け取るように変更されました。WalkFuncはファイルとディレクトリの両方の処理を統一します。
type WalkFunc func(path string, info os.FileInfo, err error) error
WalkFunc関数は、開くことができなかったファイルやディレクトリに対しても呼び出されます。そのような場合、エラー引数は失敗を説明します。ディレクトリの内容をスキップする場合、関数は値filepath.SkipDirを返す必要があります。
markFn := func(path string, info os.FileInfo, err error) error {
if path == "pictures" { // Will skip walking of directory pictures and its contents.
return filepath.SkipDir
}
if err != nil {
return err
}
log.Println(path)
return nil
}
err := filepath.Walk(".", markFn)
if err != nil {
log.Fatal(err)
}
更新: この変更はほとんどのコードを簡素化しますが、微妙な影響があるため、影響を受けるプログラムは手動で更新する必要があります。コンパイラは古いインターフェースを使用するコードを捕捉します。
regexp パッケージ
regexp パッケージは書き直されました。インターフェースは同じですが、サポートする正規表現の仕様は、古い「egrep」形式からRE2のそれへと変更されました。
更新: パッケージを使用するコードは、その正規表現を手動で確認する必要があります。
runtime パッケージ
Go 1 では、runtime パッケージによってエクスポートされていた API の多くが、他のパッケージによって提供される機能を優先して削除されました。runtime.Type インターフェースまたはその特定の具象型実装を使用するコードは、現在reflect パッケージを使用する必要があります。runtime.Semacquire または runtime.Semrelease を使用するコードは、チャネルまたはsync パッケージの抽象化を使用する必要があります。メモリ割り当てのデバッグのために作成された安全でない API である runtime.Alloc、runtime.Free、および runtime.Lookup 関数には、代替がありません。
以前は、runtime.MemStats はメモリ割り当てに関する統計を保持するグローバル変数であり、runtime.UpdateMemStats の呼び出しはそれが最新であることを保証していました。Go 1 では、runtime.MemStats は構造体型であり、コードはruntime.ReadMemStats を使用して現在の統計を取得する必要があります。
このパッケージには、オペレーティングシステムカーネルによって報告された、並列実行に利用可能な CPU の数を返す新しい関数runtime.NumCPUが追加されています。その値は GOMAXPROCS の設定に役立ちます。runtime.Cgocalls と runtime.Goroutines 関数は、それぞれ runtime.NumCgoCall と runtime.NumGoroutine に名前が変更されました。
更新: go fix を実行すると、関数名の変更に対するコードが更新されます。その他のコードは手動で更新する必要があります。
strconv パッケージ
Go 1 では、strconv パッケージが大幅に再構築され、C らしさを減らし、Go らしさを増しました。ただし、Atoi (int(ParseInt(x, 10, 0)) と似ています) と Itoa(x) (FormatInt(int64(x), 10)) は残っています。また、割り当てを制御するために、文字列を返すのではなくバイトスライスに追加する関数の新しいバリアントもいくつか追加されました。
この表は名前変更を要約したものです。パッケージドキュメントで詳細を確認してください。
| 古い呼び出し | 新しい呼び出し |
|---|---|
| Atob(x) | ParseBool(x) |
| Atof32(x) | ParseFloat(x, 32)§ |
| Atof64(x) | ParseFloat(x, 64) |
| AtofN(x, n) | ParseFloat(x, n) |
| Atoi(x) | Atoi(x) |
| Atoi(x) | ParseInt(x, 10, 0)§ |
| Atoi64(x) | ParseInt(x, 10, 64) |
| Atoui(x) | ParseUint(x, 10, 0)§ |
| Atoui64(x) | ParseUint(x, 10, 64) |
| Btoi64(x, b) | ParseInt(x, b, 64) |
| Btoui64(x, b) | ParseUint(x, b, 64) |
| Btoa(x) | FormatBool(x) |
| Ftoa32(x, f, p) | FormatFloat(float64(x), f, p, 32) |
| Ftoa64(x, f, p) | FormatFloat(x, f, p, 64) |
| FtoaN(x, f, p, n) | FormatFloat(x, f, p, n) |
| Itoa(x) | Itoa(x) |
| Itoa(x) | FormatInt(int64(x), 10) |
| Itoa64(x) | FormatInt(x, 10) |
| Itob(x, b) | FormatInt(int64(x), b) |
| Itob64(x, b) | FormatInt(x, b) |
| Uitoa(x) | FormatUint(uint64(x), 10) |
| Uitoa64(x) | FormatUint(x, 10) |
| Uitob(x, b) | FormatUint(uint64(x), b) |
| Uitob64(x, b) | FormatUint(x, b) |
更新: go fix を実行すると、変更の影響を受けるほとんどすべてのコードが更新されます。
§ Atoi は残りますが、Atoui と Atof32 は残らないため、手動で追加する必要があるキャストが必要になる場合があります。go fix ツールはこれについて警告します。
template パッケージ
template および exp/template/html パッケージは、text/template および html/template に移動しました。より重要なのは、これらのパッケージへのインターフェースが簡素化されたことです。テンプレート言語は同じですが、「テンプレートセット」の概念はなくなっており、パッケージの関数とメソッドはそれに応じて変更され、多くの場合削除されました。
セットの代わりに、Template オブジェクトは複数の名前付きテンプレート定義を含むことができ、実質的にテンプレート呼び出しのための名前空間を構築します。テンプレートは、それに関連付けられている他のテンプレートを呼び出すことができますが、それに関連付けられているテンプレートのみです。テンプレートを関連付ける最も簡単な方法は、それらを一緒に解析することであり、これはパッケージの新しい構造によってより簡単になりました。
更新: インポートは fix ツールによって更新されます。単一テンプレートの使用は、ほとんど影響を受けません。複数のテンプレートを組み合わせて使用するコードは、手動で更新する必要があります。text/template のドキュメントの例がガイダンスを提供できます。
testing パッケージ
testing パッケージには、ベンチマーク関数への引数として渡される B 型があります。Go 1 では、B には T のメソッドと同様の新しいメソッドが追加され、ロギングと失敗報告が可能になりました。
func BenchmarkSprintf(b *testing.B) {
// Verify correctness before running benchmark.
b.StopTimer()
got := fmt.Sprintf("%x", 23)
const expect = "17"
if expect != got {
b.Fatalf("expected %q; got %q", expect, got)
}
b.StartTimer()
for i := 0; i < b.N; i++ {
fmt.Sprintf("%x", 23)
}
}
更新: 既存のコードは影響を受けませんが、println または panic を使用するベンチマークは新しいメソッドを使用するように更新する必要があります。
testing/script パッケージ
testing/script パッケージは削除されました。これは不必要なものでした。
更新: 影響を受けるコードはおそらくありません。
unsafe パッケージ
Go 1 では、unsafe.Typeof、unsafe.Reflect、unsafe.Unreflect、unsafe.New、および unsafe.NewArray 関数は削除されました。これらは、reflect パッケージによって提供されるより安全な機能を重複していました。
更新: これらの関数を使用するコードは、reflect パッケージを使用するように書き換える必要があります。encoding/gob とプロトコルバッファライブラリの変更は、例として役立つかもしれません。
url パッケージ
Go 1 では、url.URL 型のいくつかのフィールドが削除または置き換えられました。
String メソッドは、必要に応じて URL のすべてのフィールドを使用して、エンコードされた URL 文字列を予測可能に再構築するようになりました。結果の文字列にはパスワードがエスケープされなくなります。
Raw フィールドは削除されました。ほとんどの場合、String メソッドで代用できます。
古い RawUserinfo フィールドは、*net.Userinfo 型の User フィールドに置き換えられました。この型の値は、新しいnet.User およびnet.UserPassword 関数を使用して作成できます。EscapeUserinfo および UnescapeUserinfo 関数もなくなりました。
RawAuthority フィールドは削除されました。同じ情報は Host および User フィールドで利用できます。
RawPath フィールドと EncodedPath メソッドは削除されました。ルート付き URL (スキーマの後にスラッシュがある URL) のパス情報は、デコードされた形式で Path フィールドにのみ利用できるようになりました。場合によっては、デコードプロセスで失われた情報を取得するためにエンコードされたデータが必要になることがあります。これらのケースは、URL が構築されたデータにアクセスして処理する必要があります。
"mailto:dev@golang.org?subject=Hi" のようなルート化されていないパスを持つ URL も異なる方法で処理されます。OpaquePath ブールフィールドは削除され、そのような URL のエンコードされたパスを保持するための新しい Opaque 文字列フィールドが導入されました。Go 1 では、引用された URL は次のように解析されます。
URL{
Scheme: "mailto",
Opaque: "dev@golang.org",
RawQuery: "subject=Hi",
}
URL に新しいRequestURI メソッドが追加されました。
ParseWithReference 関数は ParseWithFragment に名前が変更されました。
更新: 古いフィールドを使用するコードはコンパイルに失敗し、手動で更新する必要があります。意味論的な変更により、fix ツールによる自動更新は困難です。
go コマンド
Go 1 では、Go パッケージとコマンドの取得、ビルド、およびインストールを行うツールであるgo コマンドが導入されました。go コマンドは makefile を廃止し、Go ソースコードを使用して依存関係を見つけ、ビルド条件を決定します。ほとんどの既存の Go プログラムは、ビルドに makefile を必要としなくなります。
go コマンドの入門についてはGo コードの書き方を、詳細についてはgo コマンドドキュメントを参照してください。
更新: Go プロジェクトの古い makefile ベースのビルドインフラストラクチャ (Make.pkg、Make.cmd など) に依存するプロジェクトは、Go コードのビルドに go コマンドを使用するように切り替え、必要に応じて、補助的なビルドタスクを実行するために makefile を書き直す必要があります。
cgo コマンド
Go 1 では、cgo コマンドは、//export 行を含むパッケージのために生成される異なる _cgo_export.h ファイルを使用します。_cgo_export.h ファイルは、現在 C プリミティブコメントで始まっており、エクスポートされた関数定義がそこで定義された型を使用できるようにしています。これにより、プリミティブが複数回コンパイルされることになるため、//export を使用するパッケージは、C プリミティブに関数定義や変数初期化を配置してはなりません。
パッケージリリース
Go 1 に関連する最も重要な変更点の 1 つは、事前パッケージ化されたダウンロード可能なディストリビューションの提供です。これらはアーキテクチャとオペレーティングシステム (Windows を含む) の多くの組み合わせで利用可能であり、リストは今後増えていくでしょう。インストール詳細はGetting Startedページで説明されており、ディストリビューション自体はダウンロードページにリストされています。