[インデックス 11950] ファイルの概要
このコミットは、Go言語のドキュメンテーションツールであるgodoc
におけるExample関数の出力表示方法に関する重要な変更を導入しています。具体的には、Example関数の期待される出力の記述方法を、従来のExample関数直前のコメントから、関数本体の末尾に// Output:
というプレフィックスを付けたコメントとして記述する新しい規約へと移行しています。これにより、Exampleコードの可読性が向上し、特にファイル全体をExampleとして扱う場合に、出力がコードの自然な流れの中に組み込まれるようになります。
コミット
commit 11e113db573369e1fd5f92844269d31ae3815c25
Author: Andrew Gerrand <adg@golang.org>
Date: Thu Feb 16 11:50:28 2012 +1100
godoc: make example code more readable with new comment convention
go/doc: move Examples to go/ast
cmd/go: use go/doc to read examples
src/pkg: update examples to use new convention
This is to make whole file examples more readable. When presented as a
complete function, preceding an Example with its output is confusing.
The new convention is to put the expected output in the final comment
of the example, preceded by the string "output:" (case insensitive).
An idiomatic example looks like this:
// This example demonstrates Foo by doing bar and quux.
func ExampleFoo() {
// example body that does bar and quux
// Output:
// example output
}
R=rsc, gri
CC=golang-dev
https://golang.org/cl/5673053
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/11e113db573369e1fd5f92844269d31ae3815c25
元コミット内容
このコミットの元の内容は、Go言語のgodoc
ツールにおけるExampleコードの表示方法を改善することに焦点を当てています。主な変更点は以下の通りです。
- 新しいコメント規約の導入: Example関数の期待される出力を、関数本体の最後のコメントとして記述する新しい規約を導入しました。このコメントは
// Output:
(大文字・小文字を区別しない)で始まり、その後に期待される出力が続きます。 go/doc
からgo/ast
へのExamples
関数の移動: Example関数を解析するロジックが、go/doc
パッケージからgo/ast
パッケージへ移動されました。これにより、Exampleの解析がより低レベルのAST(抽象構文木)レベルで行われるようになり、より柔軟な処理が可能になります。cmd/go
の更新:go test
コマンドがExampleを読み込む際に、新しいgo/ast
パッケージの機能を利用するように更新されました。- 既存のExampleコードの更新:
src/pkg
以下の既存のExampleコードが、新しいコメント規約に準拠するように修正されました。
この変更の目的は、特にファイル全体をExampleとして表示する場合に、Exampleコードの可読性を高めることです。従来の方式では、Example関数の前に出力コメントが置かれていたため、コードと出力の関連性が分かりにくくなることがありました。新しい規約により、出力がコードの実行結果として自然に配置され、理解しやすくなります。
変更の背景
Go言語のgodoc
ツールは、ソースコードから直接ドキュメンテーションを生成する強力な機能を提供しています。その中でも、Example関数は、コードの具体的な使用例を示すために非常に有用な機能です。Example関数は、Example
というプレフィックスを持つ関数として定義され、go test
コマンドによって実行され、その出力がgodoc
によってドキュメンテーションに組み込まれます。
このコミットが行われた2012年2月時点では、Example関数の期待される出力は、Example関数の直前のコメントブロックに記述されていました。例えば、以下のような形式です。
// hello
func ExampleHello() {
fmt.Println("hello")
}
この形式は、短いExampleでは問題ありませんでしたが、Example関数がファイル全体をカバーするような、より複雑なシナリオでは問題が生じました。特に、godoc
がExampleコードを表示する際に、Example関数全体がそのまま表示されるため、その前に置かれた出力コメントが、あたかもExampleコードの一部であるかのように見えてしまい、混乱を招く可能性がありました。
このコミットの背景には、このような「ファイル全体Example」の可読性を向上させたいという明確な意図がありました。開発者は、Exampleコードとそれに対応する出力がより自然な形で関連付けられることを望んでいました。これにより、ユーザーがドキュメンテーションを読んだ際に、Exampleコードが何を行い、どのような結果を生成するのかを直感的に理解できるようになります。
また、go/doc
パッケージがExampleの解析を担当していましたが、より低レベルでASTを直接操作できるgo/ast
パッケージにExample解析ロジックを移動することで、将来的な拡張性や柔軟性を確保するという技術的な背景もありました。
前提知識の解説
このコミットを理解するためには、以下のGo言語の概念とツールに関する知識が役立ちます。
1. Go言語のExample関数
Go言語では、パッケージの使用例を示すために特別な関数を記述できます。これらの関数は「Example関数」と呼ばれ、以下の命名規則に従います。
func Example()
: パッケージ全体のExample。func ExampleF()
: 関数F
のExample。func ExampleT()
: 型T
のExample。func ExampleT_M()
: 型T
のメソッドM
のExample。
Example関数は、通常_test.go
ファイル内に記述されます。go test
コマンドを実行すると、Example関数も実行され、その標準出力がキャプチャされます。
2. godoc
ツール
godoc
は、Go言語のソースコードからドキュメンテーションを生成し、Webブラウザで表示するためのツールです。godoc
は、パッケージのコメント、関数、型、変数、定数などの定義を解析し、それらを整形して表示します。Example関数が記述されている場合、godoc
はそのExampleコードと、go test
によってキャプチャされた出力をドキュメンテーションに含めます。
3. go test
コマンド
go test
コマンドは、Goパッケージのテストを実行するための主要なツールです。これには、ユニットテスト、ベンチマークテスト、そしてExample関数の実行が含まれます。Example関数が実行される際、その標準出力はキャプチャされ、Example関数のコメントに記述された期待される出力と比較されます。一致しない場合、テストは失敗します。
4. go/ast
パッケージ
go/ast
パッケージは、Go言語のソースコードの抽象構文木(AST: Abstract Syntax Tree)を表現するためのデータ構造と関数を提供します。ASTは、ソースコードの構造を木構造で表現したもので、コンパイラやツールがコードを解析するために使用します。このパッケージを使用することで、Goのコードをプログラム的に検査、変更、生成することができます。
5. go/doc
パッケージ
go/doc
パッケージは、go/ast
パッケージによって生成されたASTから、Goパッケージのドキュメンテーションを抽出するための機能を提供します。このパッケージは、コメント、宣言、Example関数などを解析し、それらを構造化されたドキュメンテーションデータとして提供します。
6. コメントの役割
Go言語では、コメントは単なる説明文以上の役割を果たすことがあります。特に、パッケージ、関数、型、変数などの宣言の直前に記述されたコメントは、godoc
によってドキュメンテーションとして扱われます。Example関数の出力コメントも、このドキュメンテーション生成プロセスの一部として特別に扱われます。
技術的詳細
このコミットの技術的な変更は、主に以下の3つの領域にわたります。
1. Example出力の新しい解析ロジック
最も重要な変更は、Example関数の期待される出力を解析する方法です。
従来のgo/doc
パッケージでは、Example関数のDoc
フィールド(Example関数宣言の直前のコメント)から出力を取得していました。
新しいアプローチでは、go/ast
パッケージに移動されたExamples
関数内で、Example関数の本体内のコメントを走査し、// Output:
で始まる最後のコメントを探します。
src/pkg/go/ast/example.go
:Example
構造体にCode
フィールド(ast.Node
型)とComments
フィールド([]*ast.CommentGroup
型)が追加されました。これにより、Exampleのコード本体と関連するコメントグループを直接参照できるようになります。Examples
関数は、*ast.Package
ではなく、可変引数...*ast.File
を受け取るように変更されました。これにより、個々のファイルからExampleを抽出する柔軟性が向上します。exampleOutput
という新しいヘルパー関数が導入されました。この関数は、*ast.FuncDecl
(Example関数)と関連するコメントグループを受け取り、関数本体内のコメントを逆順に走査します。outputPrefix = regexp.MustCompile(
(?i)^[[:space:]]*output:)
という正規表現を使用して、// Output:
(大文字・小文字を区別しない)で始まるコメントを探し、その後のテキストをExampleの出力として抽出します。
2. go/doc
からgo/ast
へのExample解析ロジックの移動
src/pkg/go/doc/example.go
からsrc/pkg/go/ast/example.go
へのファイル移動: Example解析のコアロジックがgo/doc
パッケージからgo/ast
パッケージに移動されました。これは、Exampleの解析がASTの構造に密接に関連しているため、より低レベルのASTパッケージに配置することが適切であるという設計判断に基づいています。これにより、go/ast
がExampleの構造を直接理解し、go/doc
はそれを消費する役割に特化できるようになります。go/doc
パッケージ内のExamples
関数は削除され、代わりにgo/ast.Examples
を呼び出すように変更されました。
3. godoc
とcmd/go
の更新
src/cmd/godoc/godoc.go
:example_htmlFunc
関数のシグネチャが変更され、[]*doc.Example
の代わりに[]*ast.Example
を受け取るようになりました。- Exampleコードの表示ロジックが更新され、
eg.Code
とeg.Comments
を使用して、新しいコメント規約に基づいて出力を適切に処理するようになりました。特に、exampleOutputRx
という正規表現(regexp.MustCompile(
(?i)//[[:space:]]*output:)
)を使用して、Exampleコード内の// Output:
コメントを検出し、その部分をHTML出力から除外する処理が追加されました。これにより、godoc
のWebページ上でExampleコードが表示される際に、// Output:
行が重複して表示されるのを防ぎます。
src/cmd/go/test.go
:testFuncs.load
関数内で、Example関数の解析にast.Examples(f)
を使用するように変更されました。これにより、go test
コマンドがExampleを実行する際に、新しいgo/ast
パッケージのExample解析ロジックが利用されるようになります。- Exampleの出力が空の場合に実行しないというロジックは維持されていますが、出力の取得元が
f.Doc.Text()
からe.Output
(ast.Example
構造体から取得)に変更されました。
これらの変更により、GoのExampleシステム全体が、新しい出力コメント規約に準拠し、より堅牢で一貫性のある動作をするようになりました。
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更は、主に以下のファイルに集中しています。
-
src/pkg/go/{doc => ast}/example.go
(ファイル移動と内容変更):- ファイルが
src/pkg/go/doc/example.go
からsrc/pkg/go/ast/example.go
に移動されました。 Example
構造体の定義が変更され、Body *printer.CommentedNode
がCode Node
とComments []*CommentGroup
に分割されました。Examples
関数のシグネチャがpkg *ast.Package
からfiles ...*File
に変更されました。exampleOutput
という新しい関数が追加され、Example関数の本体内のコメントから// Output:
で始まる行を解析して出力を抽出するロジックが実装されました。
--- a/src/pkg/go/doc/example.go +++ b/src/pkg/go/ast/example.go @@ -2,37 +2,37 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Extract example functions from package ASTs. +// Extract example functions from file ASTs. -package doc +package ast import ( - "go/ast" - "go/printer" "go/token" + "regexp" "strings" "unicode" "unicode/utf8" ) type Example struct { - Name string // name of the item being demonstrated - Body *printer.CommentedNode // code - Output string // expected output + Name string // name of the item being exemplified + Code Node + Comments []*CommentGroup + Output string // expected output } -func Examples(pkg *ast.Package) []*Example { +func Examples(files ...*File) []*Example { var list []*Example - for _, file := range pkg.Files { + for _, file := range files { \thasTests := false // file contains tests or benchmarks \tnumDecl := 0 // number of non-import declarations in the file \tvar flist []*Example \tfor _, decl := range file.Decls { - \t\tif g, ok := decl.(*ast.GenDecl); ok && g.Tok != token.IMPORT { + \t\tif g, ok := decl.(*GenDecl); ok && g.Tok != token.IMPORT { \t\t\tnumDecl++ \t\t\tcontinue \t\t}\n- \t\tf, ok := decl.(*ast.FuncDecl) + \t\tf, ok := decl.(*FuncDecl) \t\tif !ok { \t\t\tcontinue \t\t}\n@@ -46,25 +46,47 @@ func Examples(pkg *ast.Package) []*Example { \t\t\t\tcontinue \t\t\t}\n \t\tflist = append(flist, &Example{\n- \t\t\t\tName: name[len("Example"):],\n- \t\t\t\tBody: &printer.CommentedNode{\n- \t\t\t\t\tNode: f.Body,\n- \t\t\t\t\tComments: file.Comments,\n- \t\t\t\t},\n- \t\t\t\tOutput: f.Doc.Text(), + \t\t\t\tName: name[len("Example"):],\n+ \t\t\t\tCode: f.Body,\n+ \t\t\t\tComments: file.Comments,\n+ \t\t\t\tOutput: exampleOutput(f, file.Comments),\n \t\t})\n \t}\n \tif !hasTests && numDecl > 1 && len(flist) == 1 {\n \t\t// If this file only has one example function, some\n \t\t// other top-level declarations, and no tests or\n \t\t// benchmarks, use the whole file as the example.\n- \t\t\tflist[0].Body.Node = file + \t\t\tflist[0].Code = file \t\t}\n \tlist = append(list, flist...)\n }\n return list\n }\n \n +var outputPrefix = regexp.MustCompile(`(?i)^[[:space:]]*output:`)\n +\n +func exampleOutput(fun *FuncDecl, comments []*CommentGroup) string {\n +\t// find the last comment in the function\n +\tvar last *CommentGroup\n +\tfor _, cg := range comments {\n +\t\tif cg.Pos() < fun.Pos() {\n +\t\t\tcontinue\n +\t\t}\n +\t\tif cg.End() > fun.End() {\n +\t\t\tbreak\n +\t\t}\n +\t\tlast = cg\n +\t}\n +\tif last != nil {\n +\t\t// test that it begins with the correct prefix\n +\t\ttext := last.Text()\n +\t\tif loc := outputPrefix.FindStringIndex(text); loc != nil {\n +\t\t\treturn strings.TrimSpace(text[loc[1]:])\n +\t\t}\n +\t}\n +\treturn "" // no suitable comment found\n +}\n +\n // isTest tells whether name looks like a test, example, or benchmark.\n // It is a Test (say) if there is a character after Test that is not a\n // lower-case letter. (We don't want Testiness.)
- ファイルが
-
src/cmd/godoc/godoc.go
(Example表示ロジックの更新):example_htmlFunc
関数がast.Example
型を受け取るように変更されました。- Exampleコードから
// Output:
コメントを削除するための正規表現exampleOutputRx
が追加され、HTML生成時にこのコメントが重複して表示されないように処理が加えられました。
--- a/src/cmd/godoc/godoc.go +++ b/src/cmd/godoc/godoc.go @@ -499,7 +499,9 @@ func startsWithUppercase(s string) bool { return unicode.IsUpper(r) } -func example_htmlFunc(funcName string, examples []*doc.Example, fset *token.FileSet) string { +var exampleOutputRx = regexp.MustCompile(`(?i)//[[:space:]]*output:`) + +func example_htmlFunc(funcName string, examples []*ast.Example, fset *token.FileSet) string { var buf bytes.Buffer for _, eg := range examples { \tname := eg.Name @@ -517,16 +519,28 @@ func example_htmlFunc(funcName string, examples []*doc.Example, fset *token.File \t}\n \n \t// print code\n - \tcode := node_htmlFunc(eg.Body, fset) + \tcnode := &printer.CommentedNode{Node: eg.Code, Comments: eg.Comments} + \tcode := node_htmlFunc(cnode, fset) + \tout := eg.Output +\n + \t// additional formatting if this is a function body \tif len(code) > 0 && code[0] == '{' { - \t\t// unindent and remove surrounding braces + \t\t// unindent \t\tcode = strings.Replace(code, "\n ", "\n", -1) + \t\t// remove surrounding braces \t\tcode = code[2 : len(code)-2] + \t\t// remove output comment + \t\tif loc := exampleOutputRx.FindStringIndex(code); loc != nil { + \t\t\tcode = strings.TrimSpace(code[:loc[0]]) + \t\t}\n + \t} else {\n + \t\t// drop output, as the output comment will appear in the code + \t\tout = "" \t}\n \n \terr := exampleHTML.Execute(&buf, struct {\n \t\tName, Code, Output string\n - \t}{eg.Name, code, eg.Output}) + \t}{eg.Name, code, out}) \tif err != nil { \t\tlog.Print(err) \t}\n@@ -552,7 +566,6 @@ func example_nameFunc(s string) string { func example_suffixFunc(name string) string { _, suffix := splitExampleName(name) return suffix -\n } func splitExampleName(s string) (name, suffix string) { @@ -966,7 +979,7 @@ type PageInfo struct { FSet *token.FileSet // corresponding file set PAst *ast.File // nil if no single AST with package exports PDoc *doc.Package // nil if no single package documentation - Examples []*doc.Example // nil if no example code + Examples []*ast.Example // nil if no example code Dirs *DirList // nil if no directory information DirTime time.Time // directory time stamp DirFlat bool // if set, show directory in a flat (non-indented) manner @@ -1115,7 +1128,7 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf }\n \n // get examples from *_test.go files\n - var examples []*doc.Example + var examples []*ast.Example filter = func(d os.FileInfo) bool { \treturn isGoFile(d) && strings.HasSuffix(d.Name(), "_test.go") }\n@@ -1123,7 +1136,11 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf \tlog.Println("parsing test files:", err) } else {\n \tfor _, testpkg := range testpkgs {\n - \t\texamples = append(examples, doc.Examples(testpkg)...) + \t\tvar files []*ast.File + \t\tfor _, f := range testpkg.Files { + \t\t\tfiles = append(files, f) + \t\t}\n + \t\texamples = append(examples, ast.Examples(files...)...) \t}\n }\n
-
src/cmd/go/test.go
(Example読み込みロジックの更新):testFuncs.load
関数内で、Exampleの読み込みにast.Examples(f)
が使用されるようになりました。これにより、go test
がExampleの出力を解析する際に、新しい規約が適用されます。
--- a/src/cmd/go/test.go +++ b/src/cmd/go/test.go @@ -183,9 +183,9 @@ where xxx is a suffix not beginning with an upper case letter. Here is an example of an example: - // The output of this example function. func ExamplePrintln() { Println("The output of this example function.") + // Output: The output of this example function. } The entire test file is presented as the example when it contains a single @@ -717,17 +717,16 @@ func (t *testFuncs) load(filename, pkg string, seen *bool) error { case isTest(name, "Benchmark"): t.Benchmarks = append(t.Benchmarks, testFunc{pkg, name, ""}) *seen = true - case isTest(name, "Example"): - output := n.Doc.Text() - if output == "" { - // Don't run examples with no output. - continue - } - t.Examples = append(t.Examples, testFunc{pkg, name, output}) - *seen = true } } -\n + for _, e := range ast.Examples(f) { + if e.Output == "" { + // Don't run examples with no output. + continue + } + t.Examples = append(t.Examples, testFunc{pkg, "Example" + e.Name, e.Output}) + *seen = true + } return nil }
-
src/pkg/testing/testing.go
(Exampleドキュメントの更新):testing
パッケージのドキュメントが更新され、新しい// Output:
コメント規約が説明されました。
--- a/src/pkg/testing/testing.go +++ b/src/pkg/testing/testing.go @@ -38,16 +38,25 @@ // }\n // }\n //\n -// The package also runs and verifies example code. Example functions\n -// include an introductory comment that is compared with the standard output\n -// of the function when the tests are run, as in this example of an example:\n +// The package also runs and verifies example code. Example functions may\n +// include a concluding comment that begins with "Output:" and is compared with\n +// the standard output of the function when the tests are run, as in these\n +// examples of an example:\n //\n -// // hello // func ExampleHello() { // fmt.Println("hello") +// // Output: hello // }\n //\n -// Example functions without comments are compiled but not executed. +// func ExampleSalutations() { +// fmt.Println("hello, and") +// fmt.Println("goodbye") +// // Output:\n +// // hello, and\n +// // goodbye\n +// }\n +//\n +// Example functions without output comments are compiled but not executed. // // The naming convention to declare examples for a function F, a type T and\n // method M on type T are:
これらの変更は、GoのExampleシステムがどのようにExampleコードを解析し、その出力をドキュメンテーションに組み込むかという、その根幹部分に影響を与えています。
コアとなるコードの解説
src/pkg/go/ast/example.go
の変更
このファイルは、Example関数の解析ロジックの新しい本拠地となります。
-
Example
構造体:type Example struct { Name string // name of the item being exemplified Code Node Comments []*CommentGroup Output string // expected output }
Code
フィールドは、Example関数の本体(またはファイル全体Exampleの場合はファイル全体)のASTノードを保持します。Comments
フィールドは、そのExampleに関連するすべてのコメントグループを保持します。これにより、exampleOutput
関数がExample関数内のコメントを効率的に検索できるようになります。 -
Examples
関数:func Examples(files ...*File) []*Example { // ... flist = append(flist, &Example{ Name: name[len("Example"):], Code: f.Body, // Example関数の本体をCodeとして設定 Comments: file.Comments, // ファイル全体のコメントを渡す Output: exampleOutput(f, file.Comments), // 新しいヘルパー関数で出力を抽出 }) // ... }
この関数は、与えられたGoのASTファイルからExample関数を抽出し、
Example
構造体のスライスとして返します。重要なのは、Output
フィールドがexampleOutput
ヘルパー関数によって設定される点です。 -
exampleOutput
関数:var outputPrefix = regexp.MustCompile(`(?i)^[[:space:]]*output:`) func exampleOutput(fun *FuncDecl, comments []*CommentGroup) string { var last *CommentGroup for _, cg := range comments { if cg.Pos() < fun.Pos() { // Example関数の開始位置より前のコメントはスキップ continue } if cg.End() > fun.End() { // Example関数の終了位置より後のコメントはスキップ break } last = cg // Example関数内のコメントを順に取得 } if last != nil { text := last.Text() if loc := outputPrefix.FindStringIndex(text); loc != nil { return strings.TrimSpace(text[loc[1]:]) // "output:"以降のテキストを抽出 } } return "" // 適切なコメントが見つからない場合は空文字列 }
この関数は、Example関数のASTノードと、そのファイル内のすべてのコメントグループを受け取ります。Example関数内のコメントのみを対象とし、その中で最後に現れる
// Output:
で始まるコメントを探します。正規表現outputPrefix
は、大文字・小文字を区別せずにoutput:
という文字列を検出します。検出された場合、そのプレフィックス以降のテキストがExampleの期待される出力として返されます。
src/cmd/godoc/godoc.go
の変更
このファイルは、godoc
がExampleをHTMLとして表示する方法を制御します。
example_htmlFunc
関数:var exampleOutputRx = regexp.MustCompile(`(?i)//[[:space:]]*output:`) func example_htmlFunc(funcName string, examples []*ast.Example, fset *token.FileSet) string { // ... if len(code) > 0 && code[0] == '{' { // ... if loc := exampleOutputRx.FindStringIndex(code); loc != nil { code = strings.TrimSpace(code[:loc[0]]) // Outputコメントをコードから削除 } } else { // drop output, as the output comment will appear in the code out = "" // ファイル全体Exampleの場合、Outputコメントはコード内に含まれるため、別途出力しない } // ... }
exampleOutputRx
は、exampleOutput
関数で使用されるoutputPrefix
とほぼ同じ正規表現ですが、こちらはgodoc
のHTML出力から// Output:
コメント行を削除するために使用されます。これにより、ExampleコードがHTMLとして表示される際に、// Output:
行がコードの一部として表示されず、重複を避けることができます。ファイル全体Exampleの場合、out
変数を空にすることで、godoc
がExampleの出力を別途表示するのではなく、コード内のコメントとしてのみ表示されるようにします。
src/cmd/go/test.go
の変更
このファイルは、go test
コマンドがExampleを実行する方法を制御します。
testFuncs.load
関数:func (t *testFuncs) load(filename, pkg string, seen *bool) error { // ... for _, e := range ast.Examples(f) { // ast.Examplesを使用 if e.Output == "" { // Don't run examples with no output. continue } t.Examples = append(t.Examples, testFunc{pkg, "Example" + e.Name, e.Output}) *seen = true } return nil }
go test
は、Example関数を読み込む際に、新しいast.Examples
関数を使用するようになりました。これにより、go test
も新しい// Output:
コメント規約に従ってExampleの出力を取得し、テストの比較に使用します。
これらの変更により、GoのExampleシステムは、Exampleコードの可読性を向上させ、より自然な形で出力と関連付けられるようになりました。
関連リンク
- Go言語のドキュメンテーション: https://go.dev/doc/
godoc
コマンドのドキュメンテーション: https://pkg.go.dev/cmd/godocgo test
コマンドのドキュメンテーション: https://pkg.go.dev/cmd/go#hdr-Test_packagesgo/ast
パッケージのドキュメンテーション: https://pkg.go.dev/go/astgo/doc
パッケージのドキュメンテーション: https://pkg.go.dev/go/doc
参考にした情報源リンク
- Go言語の公式リポジトリ: https://github.com/golang/go
- このコミットのChange List (CL): https://golang.org/cl/5673053 (コミットメッセージに記載)
- Go Blog: Organizing Go code (2011年10月): https://go.dev/blog/organizing-go-code (Example関数の初期の概念について触れている可能性)
- Go Blog: Go's Test Philosophy (2014年3月): https://go.dev/blog/go-test-philosophy (Exampleテストの重要性について触れている可能性)
- Go言語のIssueトラッカー (関連する議論がある可能性): https://github.com/golang/go/issues
- Go言語のメーリングリスト (関連する議論がある可能性): https://groups.google.com/g/golang-nuts
- Go言語のソースコード (特に
src/cmd/go
,src/cmd/godoc
,src/pkg/go/ast
,src/pkg/testing
ディレクトリ)