[インデックス 10710] ファイルの概要
このコミットは、Go 1リリースに向けたドキュメントの更新と、それに伴うパッケージの変更に関する説明を主に行っています。具体的には、doc/go1.html、doc/go1.tmpl、doc/progs/go1.goの3つのファイルが変更されています。
コミット
doc/go1: よりシンプルなパッケージの変更
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/ebdcbf1cdc3309c6cd234d93ae033937ce89a1fb
元コミット内容
doc/go1: the simpler package changes
R=golang-dev, fullung, dsymonds, r, adg
CC=golang-dev
https://golang.org/cl/5477056
変更の背景
このコミットは、Go言語の最初の安定版リリースであるGo 1の準備の一環として行われました。Go 1では、言語の安定性と互換性を確保するために、多くのAPIやパッケージに重要な変更が加えられました。このコミットの主な目的は、これらの変更、特にエラーハンドリングの改善、パッケージの再編成(exp、oldディレクトリへの移動、一部パッケージの削除)、およびstrconvパッケージの改良について、公式ドキュメント(doc/go1.htmlとdoc/go1.tmpl)を更新することです。これにより、開発者がGo 1への移行をスムーズに行えるよう、変更点と対応策が明確に示されています。
前提知識の解説
- Go 1: Go言語の最初の安定版リリース。これ以降、Goの互換性ポリシーが適用され、既存のコードが将来のバージョンで動作し続けることが保証されるようになりました。
errorインターフェース: Go言語におけるエラーハンドリングの標準的な仕組み。Error() stringメソッドを持つ任意の型がerrorインターフェースを満たします。os.Error: Go 1以前に存在したエラー型。Go 1で新しいerrorインターフェースに置き換えられました。fmt.Stringer:String() stringメソッドを持つインターフェース。fmtパッケージの関数(例:fmt.Print)は、このインターフェースを満たす型の値を自動的に文字列に変換して出力します。errorインターフェースの導入により、String()とError()のメソッド名の衝突が問題となる可能性がありました。gofix: Go言語のコードを新しいAPIや言語仕様に合わせて自動的に書き換えるツール。Go 1への移行を支援するために広く利用されました。expパッケージツリー: "experimental"(実験的)の略。Go 1リリース時に標準ライブラリには含まれないが、将来的に含まれる可能性のある実験的なパッケージが置かれるディレクトリ。oldパッケージツリー: "old"(古い)の略。Go 1リリース時に非推奨となり、標準ライブラリから削除された、または別の場所に移動されたパッケージが置かれるディレクトリ。container/vector: Go 1以前に存在した、動的配列を実装するパッケージ。Go 1では、組み込みのスライス型が強化されたため、このパッケージは削除されました。syscall.Errno: システムコールエラーを表す型。Go 1では、errorインターフェースを満たすように変更されました。
技術的詳細
このコミットは、Go 1における以下の主要な技術的変更点をドキュメント化しています。
-
error型とerrorsパッケージの導入:- Go 1では、新しい組み込みインターフェース型
errorが導入されました。これは、以前のos.Error型を置き換えるもので、より中心的なエラー概念を提供します。 errorインターフェースはError() stringメソッドを持ちます。これにより、fmt.StringerインターフェースのString()メソッドとの名前の衝突を避け、意図しないインターフェースの満足を防ぎます。fmtライブラリは、String()と同様にError()メソッドを自動的に呼び出し、エラー値の簡単な出力に対応します。- 新しい
errorsパッケージが導入され、文字列からerror型を生成するNew(text string) error関数が提供されます。これは以前のos.NewErrorを置き換えます。 - 標準パッケージはすべて新しい
errorインターフェースを使用するように更新され、os.Errorは削除されました。 - 既存のコードの更新については、
gofixツールがほとんどの変更を自動的に処理しますが、Stringメソッドを持つ独自のエラー型を定義している場合は、手動でメソッド名をErrorに変更する必要があります。
- Go 1では、新しい組み込みインターフェース型
-
システムコールエラー (
errno) の変更:- Go 1では、
syscallパッケージがシステムコールエラーに対して、プレーンな整数errno値ではなくerror型を返すようになりました。 - Unixシステムでは、
syscall.Errno型がerrorインターフェースを満たすように実装され、以前のos.Errnoを置き換えます。
- Go 1では、
-
strconvパッケージの変更:strconvパッケージは大幅に再設計され、よりGoらしい(C言語的ではない)APIになりました。Atoi関数は残されていますが、ParseInt(x, 10, 0)のようなより汎用的な関数が推奨されます。- 多くの関数が
intやfloatではなく文字列を返すようになり、メモリ割り当ての制御が容易になりました。
-
パッケージツリーの再編成 (
exp,old, 削除されたパッケージ):expディレクトリへの移動:ebnf、go/types、http/spdyなどの実験的なパッケージはexpディレクトリに移動され、Go 1の標準リリースには含まれなくなりました。これらはexp/ebnfのようにexp/プレフィックス付きで利用可能です。関連するコマンド(gotype、ebnflint)もexp/gotype、exp/ebnflintに移動しました。これらのパッケージを使用するコードは手動で更新する必要があります。oldディレクトリへの移動:old/netchan、old/regexp、old/templateなどの非推奨パッケージはoldディレクトリに移動され、Go 1の標準リリースには含まれなくなりました。これらのパッケージを使用するコードも手動で更新する必要があります。- パッケージの削除:
container/vector、exp/datafmt、go/typechecker、try、およびgotryコマンドが完全に削除されました。container/vectorを使用していたコードは、Goのスライスを直接使用するように更新する必要があります。GoコミュニティWikiの「SliceTricks」が参考になります。- その他の削除されたパッケージを使用していたコードは、再設計が必要です。
gofixツールは、これらのパッケージの移動や削除に関する警告を出すように計画されています(コミット内のTODOコメントで示唆されています)。
コアとなるコードの変更箇所
このコミットの主要な変更は、Go 1のドキュメントファイルであるdoc/go1.htmlとdoc/go1.tmplに集中しています。
-
doc/go1.htmlおよびdoc/go1.tmpl:error型とerrorsパッケージに関する新しいセクションが追加され、errorインターフェースの定義、fmtとの連携、errors.New関数の使用例、および既存コードの更新方法が詳細に説明されています。syscallパッケージのリンクがhttp://golang.org/pkg/syscallから/pkg/syscall/に変更され、相対パスになりました。strconvパッケージに関する説明が更新され、APIの変更点が記述されています。exp、oldディレクトリへのパッケージ移動、および削除されたパッケージに関する新しいセクションが追加され、それぞれのパッケージの状況と、既存コードの更新に関するガイダンスが提供されています。特に、container/vectorからスライスへの移行に関する具体的なアドバイスが含まれています。- 以前のコメントアウトされたセクション(
<!-- ... -->)が、実際のHTMLコンテンツとして追加され、パッケージの移動や削除に関する情報が公開されました。
-
doc/progs/go1.go:errorsパッケージとfmtパッケージがインポートに追加されました。errorExample()関数が追加されました。この関数は、新しいerrorインターフェースの使用例として、カスタムエラー型SyntaxErrorを定義し、そのError()メソッドがfmt.Sprintfを使用してエラーメッセージをフォーマットする方法を示しています。また、errors.Newを使用してErrSyntaxというエラー変数を定義する例も含まれています。
コアとなるコードの解説
doc/progs/go1.goに追加されたerrorExample()関数は、Go 1で導入された新しいerrorインターフェースの動作を具体的に示しています。
// START ERROR EXAMPLE OMIT
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)
}
// END ERROR EXAMPLE OMIT
func errorExample() {
var ErrSyntax = errors.New("syntax error")
_ = ErrSyntax
se := &SyntaxError{"file", 7, "error"}
got := fmt.Sprint(se)
const expect = "file:7: error"
if got != expect {
log.Fatalf("errorsPackage: expected %q got %q", expect, got)
}
}
SyntaxError構造体:File、Line、Messageというフィールドを持つカスタムエラー構造体です。Error() stringメソッド: このメソッドがSyntaxError型に実装されているため、SyntaxErrorはGoの組み込みerrorインターフェースを満たします。メソッド内ではfmt.Sprintfを使用して、ファイル名、行番号、メッセージを含む整形されたエラー文字列を生成しています。errorExample()関数:var ErrSyntax = errors.New("syntax error"):errorsパッケージのNew関数を使って、シンプルな文字列からerror型の値を生成する例です。これは、Go 1でos.NewErrorがerrors.Newに置き換えられたことを示しています。se := &SyntaxError{"file", 7, "error"}:SyntaxErrorのインスタンスを作成しています。got := fmt.Sprint(se):ここで重要なのは、fmt.SprintがSyntaxError型の変数seに対して、自動的にそのError()メソッドを呼び出し、返された文字列を結果として使用することです。これは、fmtパッケージがerrorインターフェースを認識し、そのError()メソッドをfmt.StringerのString()メソッドと同様に扱うことを示しています。if got != expect { ... }:生成されたエラー文字列が期待される形式("file:7: error")と一致するかを検証しています。
このコードは、Go 1におけるエラーハンドリングの新しいパラダイム、すなわちカスタムエラー型がError() stringメソッドを実装することでerrorインターフェースを満たし、fmtパッケージがそれを透過的に処理するという仕組みを明確に示しています。
関連リンク
- Go言語公式ドキュメント: https://golang.org/doc/
- Go言語コミュニティWiki - SliceTricks: http://code.google.com/p/go-wiki/wiki/SliceTricks (現在はGitHub Wikiに移行している可能性が高いですが、当時のリンクを記載)
参考にした情報源リンク
- GitHubコミットページ: https://github.com/golang/go/commit/ebdcbf1cdc3309c6cd234d93ae033937ce89a1fb
- Go CL 5477056: https://golang.org/cl/5477056 (Goのコードレビューシステムへのリンク)