[インデックス 11719] ファイルの概要
このコミットは、Go言語の公式仕様書である doc/go_spec.html
ファイルに対する変更です。このファイルは、Go言語の構文、セマンティクス、および標準ライブラリの動作を詳細に記述しており、Go言語の設計と実装の基礎となる重要なドキュメントです。
コミット
commit 7c5d6409f50b731992e33af0c3cee23e8cc4a7c5
Author: Russ Cox <rsc@golang.org>
Date: Wed Feb 8 15:37:58 2012 -0500
spec: address CL 5647054 comments
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5641057
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/7c5d6409f50b731992e33af0c3cee23e8cc4a7c5
元コミット内容
このコミットの元の内容は、Go言語の仕様書における匿名フィールド(埋め込みフィールド)とインターフェースの埋め込みに関する記述の明確化です。具体的には、以下の2つのセクションが修正されています。
-
匿名フィールド(埋め込みフィールド)に関する記述の修正:
- 匿名フィールドの別名として「embedded field」だけでなく、「embedding of the type in the struct」という表現を追加し、より包括的な説明にしています。
- 「Such a field type must be specified as」という表現を「An embedded type must be specified as」に修正し、より簡潔で直接的な表現にしています。
-
インターフェースの埋め込みに関する記述の修正:
- インターフェースが自身を埋め込むこと、または自身を間接的に埋め込む他のインターフェースを埋め込むことができないという規則について、「directly or indirectly」という表現を「recursively」というより簡潔で技術的に正確な表現に置き換えています。
変更の背景
このコミットの背景には、Go言語の仕様書における用語の明確化と、より正確な表現への改善があります。コミットメッセージにある「spec: address CL 5647054 comments」という記述から、この変更がGo言語の変更リスト(Change List, CL)5647054に対するコメントやフィードバックに対応するものであることが示唆されます。
Go言語の仕様書は、言語の挙動を定義する最も権威あるドキュメントであり、その記述は曖昧さなく、正確である必要があります。特に、匿名フィールド(埋め込み)やインターフェースの埋め込みといったGo言語の重要な特徴に関する記述は、開発者が言語を正しく理解し、利用するために極めて重要です。
このコミットは、既存の仕様記述が一部の読者にとって不明瞭であったり、より適切な表現が存在したりする可能性があったため、その点を改善することを目的としています。特に「directly or indirectly」を「recursively」に置き換える変更は、再帰的な定義の文脈において、より専門的で簡潔な表現を用いることで、仕様の厳密性を高める意図があると考えられます。
前提知識の解説
このコミットの変更内容を理解するためには、Go言語における以下の概念を理解しておく必要があります。
1. 匿名フィールド(Anonymous Fields)と埋め込み(Embedding)
Go言語の構造体(struct)には、フィールド名を持たないフィールドを宣言することができます。これを「匿名フィールド」と呼びます。匿名フィールドは、その型が構造体に「埋め込まれる(embedded)」と表現され、埋め込まれた型のメソッドやフィールドが、あたかもその構造体自身のメソッドやフィールドであるかのように、構造体のインスタンスから直接アクセスできるようになります。これは、Goにおける「コンポジション(Composition)」を促進する強力なメカニズムであり、継承の代わりにコードの再利用を実現します。
例:
type Person struct {
Name string
Age int
}
type Employee struct {
Person // Person型を匿名フィールドとして埋め込み
ID string
}
func main() {
e := Employee{
Person: Person{Name: "Alice", Age: 30},
ID: "E123",
}
fmt.Println(e.Name) // Alice (PersonのNameフィールドに直接アクセス)
}
2. インターフェースの埋め込み(Interface Embedding)
Go言語のインターフェースは、メソッドのシグネチャの集合を定義します。一つのインターフェースが、他のインターフェースのメソッドセットを「埋め込む」ことができます。これにより、埋め込まれたインターフェースのすべてのメソッドが、埋め込む側のインターフェースのメソッドセットに含まれることになります。これは、より大きなインターフェースを、より小さなインターフェースの組み合わせで構築する際に非常に便利です。
例:
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
type ReadWriter interface {
Reader // Readerインターフェースを埋め込み
Writer // Writerインターフェースを埋め込み
}
// ReadWriterインターフェースは、ReadとWriteの両方のメソッドを持つ
3. 再帰(Recursion)
再帰とは、ある定義やプロセスが、それ自身を呼び出す、またはそれ自身を参照する構造を持つことを指します。プログラミングにおいては、関数が自分自身を呼び出す「再帰関数」が典型的な例です。データ構造の定義においても、例えばリンクリストのノードが次のノードへのポインタを持つように、再帰的な定義が用いられることがあります。このコミットの文脈では、インターフェースの埋め込みが「再帰的」に自身を参照するような循環参照を禁止するという意味で使われています。
技術的詳細
このコミットは、Go言語の仕様書 doc/go_spec.html
内の特定の文言を修正することで、匿名フィールドとインターフェースの埋め込みに関する記述の正確性と明確性を向上させています。
匿名フィールド(埋め込みフィールド)に関する修正
元の記述では、匿名フィールドを「colloquially called an embedded field」(口語的に埋め込みフィールドと呼ばれる)と説明していました。この修正では、より正式な表現として「also called an embedded field or an embedding of the type in the struct」(埋め込みフィールド、または構造体への型の埋め込みとも呼ばれる)というフレーズを追加しています。これにより、「匿名フィールド」という正式名称と、「埋め込み」という概念的な表現、そして「構造体への型の埋め込み」という具体的な操作の間の関係がより明確になります。
また、「Such a field type must be specified as」という文が「An embedded type must be specified as」に変更されています。これは、匿名フィールドが「埋め込まれた型」として機能するという事実をより直接的に表現しており、文の主語を明確にすることで、読解のしやすさを向上させています。
インターフェースの埋め込みに関する修正
インターフェースの埋め込みに関する規則では、インターフェースが自身を埋め込むこと、または自身を直接的・間接的に埋め込む他のインターフェースを埋め込むことができない、と規定されていました。この「directly or indirectly」という表現は、再帰的な参照の禁止を意図していますが、より簡潔で技術的に適切な用語である「recursively」(再帰的に)に置き換えられました。
この変更は、仕様書の記述をより厳密にし、曖昧さを排除することを目的としています。プログラミング言語の仕様において、再帰的な定義や参照の禁止は一般的な概念であり、「recursively」という単語を用いることで、その意図がより明確に伝わります。例えば、interface A
が interface B
を埋め込み、interface B
が interface A
を埋め込むような循環参照は、この規則によって禁止されます。
これらの変更は、Go言語の仕様書が、言語の挙動を正確かつ簡潔に記述するという目標を達成するための継続的な努力の一環です。
コアとなるコードの変更箇所
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -897,9 +897,9 @@ struct {
</pre>
<p>
-A field declared with a type but no explicit field name is an <i>anonymous field</i>
-(colloquially called an embedded field).
-Such a field type must be specified as
+A field declared with a type but no explicit field name is an <i>anonymous field</i>,
+also called an <i>embedded</i> field or an embedding of the type in the struct.
+An embedded type must be specified as
a type name <code>T</code> or as a pointer to a non-interface type name <code>*T</code>,
and <code>T</code> itself may not be
a pointer type. The unqualified type name acts as the field name.
@@ -1141,8 +1141,8 @@ type File interface {\n </pre>\n \n <p>\n-An interface definition for type <code>T</code> may not embed itself,\n-nor any interface type that embeds <code>T</code> directly or indirectly.\n+An interface type <code>T</code> may not embed itself\n+or any interface type that embeds <code>T</code>, recursively.\n </p>\n \n <pre>\n```
## コアとなるコードの解説
上記のdiffは、`doc/go_spec.html` ファイル内の2つの異なるセクションに対する変更を示しています。
### 1. 匿名フィールド(埋め込みフィールド)に関する変更
元の行:
`A field declared with a type but no explicit field name is an <i>anonymous field</i> (colloquially called an embedded field).`
変更後の行:
`A field declared with a type but no explicit field name is an <i>anonymous field</i>, also called an <i>embedded</i> field or an embedding of the type in the struct.`
**解説**:
この変更は、匿名フィールドの定義をより包括的にしています。以前は「口語的に埋め込みフィールドと呼ばれる」とされていましたが、新しい記述では「埋め込みフィールド、または構造体への型の埋め込みとも呼ばれる」と明確にしています。これにより、匿名フィールドがGoのコンポジションにおける「埋め込み」という概念と密接に関連していることが、より正確に伝わるようになります。
元の行:
`Such a field type must be specified as`
変更後の行:
`An embedded type must be specified as`
**解説**:
この変更は、文の主語をより明確にしています。匿名フィールドは、その型が構造体に「埋め込まれる」ため、「埋め込まれた型」という表現がより適切です。これにより、文の意図がより直接的に伝わり、読解の助けとなります。
### 2. インターフェースの埋め込みに関する変更
元の行:
`An interface definition for type <code>T</code> may not embed itself, nor any interface type that embeds <code>T</code> directly or indirectly.`
変更後の行:
`An interface type <code>T</code> may not embed itself or any interface type that embeds <code>T</code>, recursively.`
**解説**:
この変更は、インターフェースの埋め込みにおける循環参照の禁止をより簡潔かつ技術的に正確な用語で表現しています。元の「directly or indirectly」(直接的または間接的に)という表現は、再帰的な性質を示唆していましたが、新しい記述では「recursively」(再帰的に)という単一の単語に置き換えることで、その意味をより明確にしています。これは、`T` が `U` を埋め込み、`U` が `T` を埋め込むといった、任意の深さでの循環的な埋め込みが禁止されることを意味します。仕様書の厳密性を高めるための改善です。
## 関連リンク
* Go Change List 5641057: [https://golang.org/cl/5641057](https://golang.org/cl/5641057)
## 参考にした情報源リンク
* The Go Programming Language Specification: [https://go.dev/ref/spec](https://go.dev/ref/spec)
* Effective Go - Embedding: [https://go.dev/doc/effective_go#embedding](https://go.dev/doc/effective_go#embedding)
* Go by Example: Interfaces: [https://gobyexample.com/interfaces](https://gobyexample.com/interfaces)
* Go by Example: Structs: [https://gobyexample.com/structs](https://gobyexample.com/structs)