[インデックス 12234] ファイルの概要
このコミットは、Go言語の標準ライブラリ strings
パッケージ内の Count
関数の使用例(ExampleCount
)を修正し、その実行結果がGoのドキュメンテーションツールによって正しく表示されるようにするものです。具体的には、example_test.go
ファイル内の ExampleCount
関数に // Output:
コメントを追加することで、go doc
コマンドや pkg.go.dev のようなGoの公式ドキュメントサイトで、この例の出力が期待通りに表示されるようにしています。
コミット
commit b495e5c538d73b8cf0be99960c44d3ab9650ddee
Author: Robert Griesemer <gri@golang.org>
Date: Mon Feb 27 12:22:10 2012 -0800
strings: make Count example show results
Thanks to dr.volker.dobler for tracking this down.
Filed a long-term issue (3142) which may eventually
resolve this problem w/o the need for a manual fix.
R=iant
CC=golang-dev
https://golang.org/cl/5698078
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/b495e5c538d73b8cf0be99960c44d3ab9650ddee
元コミット内容
strings: make Count example show results
Thanks to dr.volker.dobler for tracking this down.
Filed a long-term issue (3142) which may eventually
resolve this problem w/o the need for a manual fix.
R=iant
CC=golang-dev
https://golang.org/cl/5698078
変更の背景
Go言語のドキュメンテーションシステムでは、_test.go
ファイル内に記述された Example
関数が特別な意味を持ちます。これらの関数は、パッケージのドキュメントにコード例として表示されるだけでなく、その出力が // Output:
コメントで指定された期待値と一致するかどうかをテストとしても実行します。
このコミットが行われる前は、strings.Count
関数の ExampleCount
関数は fmt.Println
を使用して結果を出力していましたが、その出力がドキュメントに表示されるための // Output:
コメントが欠落していました。そのため、go doc strings
コマンドやGoの公式ドキュメントサイトでこの例を見た際に、コードは表示されるものの、その実行結果が示されないという問題がありました。
dr.volker.dobler
氏がこの問題を発見し、報告したことで、Robert Griesemer 氏がこの修正を行いました。コミットメッセージには、より長期的な解決策として issue 3142 が挙げられており、将来的には手動での修正なしに同様の問題が解決される可能性が示唆されています。
前提知識の解説
Go言語の _test.go
ファイルと Example
関数
Go言語では、テストファイルは通常 _test.go
というサフィックスを持ちます。これらのファイルには、ユニットテスト、ベンチマークテスト、そして「Example」関数を記述することができます。
TestXxx
関数:func TestXxx(t *testing.T)
の形式で記述され、ユニットテストとして機能します。BenchmarkXxx
関数:func BenchmarkXxx(b *testing.B)
の形式で記述され、パフォーマンスベンチマークとして機能します。ExampleXxx
関数:func ExampleXxx()
の形式で記述され、コードの利用例を示します。これらの関数は、go test
実行時にテストとしても機能し、その出力が特定のコメントと一致するかどうかを検証します。
// Output:
コメント
Example
関数が標準出力に何かを出力する場合、その出力の期待値を // Output:
コメントの後に記述することができます。Goのテストツールは、Example
関数を実行し、その標準出力が // Output:
コメントの後に続く行と完全に一致するかどうかを検証します。
例えば、以下の Example
関数があるとします。
func ExampleHello() {
fmt.Println("Hello, world!")
// Output: Hello, world!
}
この例では、ExampleHello
関数が "Hello, world!" と出力することを期待しています。go test
を実行すると、この関数が実行され、実際に出力された文字列が // Output:
の後に続く文字列と一致するかどうかがチェックされます。一致しない場合、テストは失敗します。
さらに重要な点として、この // Output:
コメントは、go doc
コマンドや pkg.go.dev のようなGoのドキュメンテーションツールが Example
関数の出力をドキュメントに含めるために使用されます。これにより、ユーザーはコード例だけでなく、そのコードを実行した結果もドキュメント上で確認できるようになります。
strings.Count
関数
strings.Count(s, substr string) int
は、Go言語の標準ライブラリ strings
パッケージに含まれる関数です。この関数は、文字列 s
の中に、部分文字列 substr
が非オーバーラップで出現する回数を返します。
例:
strings.Count("cheese", "e")
は3
を返します。strings.Count("five", "")
は5
を返します。これは、空文字列が各ルーン(Unicodeコードポイント)の前後に、そして文字列の最後に出現すると解釈されるためです。
技術的詳細
このコミットの技術的な核心は、Goの Example
関数のテストおよびドキュメンテーションメカニズムを正しく利用することにあります。
src/pkg/strings/example_test.go
ファイルは、strings
パッケージのExample関数を定義しています。ExampleCount
関数は、strings.Count
の使用方法を示すために記述されています。
func ExampleCount() {
fmt.Println(strings.Count("cheese", "e"))
fmt.Println(strings.Count("five", "")) // before & after each rune
}
この関数は fmt.Println
を呼び出して結果を標準出力に出力しますが、Goのドキュメンテーションツールがこの出力を認識し、ドキュメントに含めるためには、特定の形式のコメントが必要です。それが // Output:
コメントです。
コミットによって追加された行は以下の通りです。
--- a/src/pkg/strings/example_test.go
+++ b/src/pkg/strings/example_test.go
@@ -41,6 +41,7 @@ func ExampleContainsAny() {\n func ExampleCount() {\n fmt.Println(strings.Count("cheese", "e"))\n fmt.Println(strings.Count("five", "")) // before & after each rune\n+\n // Output:\n // 3\n // 5\n```
追加された `// Output:` コメントブロックは、`ExampleCount` 関数が実行された際に期待される標準出力の内容を正確に記述しています。
```go
// Output:
// 3
// 5
この変更により、以下の効果が得られます。
- ドキュメントの改善:
go doc strings
や pkg.go.dev でstrings.Count
のドキュメントを見た際に、ExampleCount
のコード例だけでなく、その実行結果として3
と5
が表示されるようになります。これにより、ユーザーは関数の挙動をより直感的に理解できます。 - テストの追加:
go test strings
を実行すると、ExampleCount
関数が実行され、実際に出力された内容が// Output:
コメントに記述された内容と一致するかどうかが自動的に検証されます。これにより、Exampleコードが常に正しい出力を生成することを保証する、一種の回帰テストとしても機能します。
この修正は、Go言語のドキュメンテーションとテストの哲学に則ったものであり、コード例の品質と信頼性を向上させるための重要な変更です。
コアとなるコードの変更箇所
--- a/src/pkg/strings/example_test.go
+++ b/src/pkg/strings/example_test.go
@@ -41,6 +41,7 @@ func ExampleContainsAny() {\n func ExampleCount() {\n fmt.Println(strings.Count("cheese", "e"))\n fmt.Println(strings.Count("five", "")) // before & after each rune\n+\n // Output:\n // 3\n // 5\n```
変更は `src/pkg/strings/example_test.go` ファイルの1行の追加のみです。
## コアとなるコードの解説
追加された行は以下の通りです。
```go
// Output:
// 3
// 5
このコメントブロックは、ExampleCount
関数が標準出力に 3
と 5
を順に出力することをGoのドキュメンテーションツールとテストツールに伝えます。
// Output:
は、これ以降の行がExample関数の期待される標準出力であることを示す特別なマーカーです。// 3
は、fmt.Println(strings.Count("cheese", "e"))
の出力である3
を表します。// 5
は、fmt.Println(strings.Count("five", ""))
の出力である5
を表します。
このシンプルな追加により、ExampleCount
は単なるコード例から、ドキュメントにその結果が表示され、かつ自動テストによってその出力が検証される、より堅牢で情報量の多いExampleへと進化しました。
関連リンク
- Go CL (Code Review) リンク: https://golang.org/cl/5698078
- 関連する長期的なIssue: https://go.dev/issue/3142 (コミットメッセージで言及されている
issue (3142)
は、GoのIssueトラッカーではgo.dev/issue/3142
となります。)
参考にした情報源リンク
- Go言語の公式ドキュメント: https://go.dev/
- GoのExampleテストに関する公式ドキュメント (testingパッケージ): https://pkg.go.dev/testing#hdr-Examples
strings
パッケージのドキュメント: https://pkg.go.dev/stringsstrings.Count
関数のドキュメント: https://pkg.go.dev/strings#Count