[インデックス 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のコードレビューシステムへのリンク)