Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 1726] ファイルの概要

このコミットは、Go言語の公式仕様書である doc/go_spec.html に対する編集上の修正を多数含んでいます。主に「型 (types)」に関する記述の明確化、正確性の向上、および表現の統一を目的としています。

コミット

commit da38974c8851c06868c8d941db5aa6d44e023524
Author: Rob Pike <r@golang.org>
Date:   Mon Mar 2 19:13:40 2009 -0800

    address most of the editorial comments through "types"
    
    R=rsc
    DELTA=41  (9 added, 4 deleted, 28 changed)
    OCL=25611
    CL=25611

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/da38974c8851c06868c8d941db5aa6d44e023524

元コミット内容

このコミットは、Go言語の仕様書 doc/go_spec.html に対して、主に型に関する記述の編集上のコメントに対応するための変更を加えています。具体的には、数値型、構造体、匿名フィールド、ポインタ、可変長引数関数、スライス、マップ、チャネル、型の等価性、インターフェースの比較と代入、理想型(ideal type)に関する説明が修正されています。

変更の背景

このコミットの背景には、Go言語の初期段階における仕様書の洗練と明確化の必要性があります。Go言語は当時まだ開発途上にあり、その仕様は継続的にレビューされ、改善されていました。このコミットは、特に「型」に関するセクションにおいて、読者からのフィードバックや内部レビューで指摘された編集上の曖昧さ、不正確さ、または表現の不統一を解消することを目的としています。

Go言語の設計思想の一つに「シンプルさ」と「明確さ」があります。そのため、言語仕様書もまた、これらの原則を反映している必要があります。このコミットは、Goの型システムという言語の根幹をなす部分について、その定義と振る舞いをより正確かつ理解しやすく記述するための重要なステップでした。特に、Goの型システムは静的型付けでありながら、インターフェースによる動的な振る舞いを許容するなど、他の言語とは異なる特徴を持つため、その詳細な記述には高い精度が求められます。

前提知識の解説

このコミットの変更内容を理解するためには、以下のGo言語の基本的な概念に関する知識が必要です。

  • Goの型システム: Goは静的型付け言語であり、変数は特定の型を持ちます。型は、その変数が保持できる値の種類と、その値に対して実行できる操作を定義します。Goの型システムは、安全性と効率性を重視しており、暗黙的な型変換を最小限に抑えています。
  • 数値型: int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, complex64, complex128 など、様々なサイズの整数型、浮動小数点型、複素数型が存在します。byteuint8 のエイリアスです。Goでは、異なる数値型間の混合演算には明示的な型変換が必要です。
  • 構造体 (Structs): 構造体は、異なる型のフィールド(メンバー変数)をまとめた複合データ型です。これにより、関連するデータを一つの単位として扱うことができます。
  • 匿名フィールド (Anonymous Fields): 構造体内でフィールド名を指定せずに型のみを宣言するフィールドです。これにより、その型のメソッドやフィールドを外部から直接アクセスできるようになり、埋め込み(embedding)によるコードの再利用を促進します。
  • スライス (Slices): スライスは、Goにおける可変長シーケンス型です。配列のセグメントを参照し、動的にサイズを変更できます。スライスは内部的にポインタ、長さ、容量の3つの要素で構成されます。
  • マップ (Maps): マップは、キーと値のペアを格納するハッシュテーブルです。キーは一意であり、値にアクセスするために使用されます。
  • チャネル (Channels): チャネルは、Goのゴルーチン間で値を送受信するための通信メカニズムです。チャネルは型付けされており、特定の型の値のみを送信できます。
  • make 関数: make は、スライス、マップ、チャネルといった組み込みの参照型を初期化し、メモリを割り当てるために使用される組み込み関数です。
  • 型の等価性 (Type Equality): Goにおける型の等価性のルールは厳密です。異なる型は、たとえ基になる表現が同じであっても、通常は等価とは見なされません。
  • インターフェース (Interfaces): インターフェースは、メソッドのシグネチャの集合を定義する型です。Goでは、型がインターフェースで定義されたすべてのメソッドを実装していれば、そのインターフェースを「実装している」と見なされます(暗黙的な実装)。インターフェース変数は、任意の基になる型の値を保持できます。
  • 理想型 (Ideal Types): Goにおける数値リテラル(例: 10, 3.14)は、特定の型を持たない「理想型」として扱われます。これにより、リテラルは文脈に応じて適切な数値型に変換されます。

技術的詳細

このコミットは、Go言語の仕様書 doc/go_spec.html の複数の箇所にわたる、主に編集上の修正と明確化を行っています。以下に主要な変更点の技術的詳細を説明します。

  1. 評価順序と演算子優先順位に関する記述の削除:

    • 変更前には「可能な限り、再帰的な生成規則が評価順序と演算子優先順位を構文的に表現するために使用される」という一般的な記述がありました。これは言語仕様の具体的な内容というよりは、仕様書作成のメタな方針に関する記述であり、仕様の核心ではないため削除されました。これにより、仕様書がより直接的に言語の振る舞いを記述することに集中できるようになります。
  2. 数値型の区別に関する表現の修正:

    • byteuint8 のエイリアスであることと、移植性の問題を避けるために他のすべての数値型が区別されるという記述の順序が変更されました。これにより、文の構造が改善され、より自然な読みに変わっています。意味的な変更はありません。
  3. 構造体フィールド識別子と匿名フィールドの記述の明確化:

    • 構造体内のフィールド識別子に関する記述にコンマが追加され、文の区切りが明確になりました。
    • 匿名フィールドの型指定に関する記述でもコンマが追加され、T 自体がポインタ型やインターフェース型であってはならないという条件の読みやすさが向上しました。
    • 匿名フィールドの例 (P.T3; // the field name is the unqualified type name T3) において、コメントから「the unqualified type name」という冗長な表現が削除され、単に「the field name is T3」と簡潔に記述されるようになりました。これは、匿名フィールドの識別子がその非修飾型名であるという事実を、より直接的に示しています。
  4. ポインタの「基底型 (base type)」の強調:

    • ポインタが指す型のことを「基底型」と呼ぶ際に、引用符 (``) ではなくHTMLのイタリックタグ (<i>) が使用されるようになりました。これは、仕様書全体での用語の強調方法の統一と、より適切なセマンティックHTMLの使用を反映しています。
  5. 可変長引数関数 (Variadic Functions) の表現の改善:

    • 可変長引数関数が「任意の数(ゼロを含む)の追加引数」を受け取るという表現が、「ゼロ個以上の追加引数」というより簡潔で一般的な表現に修正されました。意味的な変更はありませんが、よりGoらしい表現になっています。
  6. スライスの初期化と nil スライスの振る舞いの明確化:

    • 初期化されていないスライスが nil であることと、その長さと容量が0であることに関する記述が、2つの独立した文に分割されました。これにより、それぞれの事実がより明確に伝わるようになりました。
    • make 関数を使ったスライスの生成例 (make([capacity]T)[0 : length]) が、より正確なGoの構文 (make([]T, capacity)[0 : length]) に修正されました。これは、make がスライス型を引数にとる際の正しい構文を反映しています。
  7. マップの初期化と容量に関する詳細の追加:

    • 初期化されていないマップが nil であるという文に句点が追加されました。
    • make 関数を使ったマップの生成例において、容量を指定しない形式 (make(map[string] int)) と容量を指定する形式 (make(map[string] int, 100)) の両方が示されるようになりました。
    • 重要な追加: 「初期容量はそのサイズを制限しない。マップは格納されるアイテムの数に合わせて成長する」という新しい段落が追加されました。これは、Goのマップの動的な性質と、make で指定する容量が単なるヒントであり、上限ではないという重要な概念を明確にしています。これは、Goのマップの内部実装(ハッシュテーブル)の振る舞いを理解する上で非常に重要です。
  8. チャネルの make 関数の例の修正:

    • make 関数を使ったチャネルの生成例 (make(chan int, 100);) から末尾のセミコロンが削除されました。Goのコード例では通常セミコロンは不要です。
  9. 型の代入に関する表現の修正:

    • 「それらは等しい型の変数に代入できる」という表現が、「値は等しい型の変数に代入できる」と修正されました。これにより、代入の主体が「型」ではなく「値」であることがより明確になりました。
  10. インターフェースへの代入における「静的型」の修正:

    • 最も重要な変更点の一つ: 「値は、その値の動的型がインターフェースを実装している場合、インターフェース変数に代入できる」という記述が、「値は、その値の静的型がインターフェースを実装している場合、インターフェース変数に代入できる」に修正されました。
      • 背景: Goにおいて、インターフェースへの代入可能性はコンパイル時に決定されます。つまり、代入される値の「静的型」(コンパイル時に既知の型)が、インターフェースで定義されたすべてのメソッドを実装しているかどうかによって判断されます。実行時に値の「動的型」がどうなるかは関係ありません。この修正は、Goの型チェックの仕組みにおける根本的な概念の正確性を保証するものです。
  11. スライスの比較に関する明確化:

    • スライスが nil とのみ比較できること、および nil スライスの条件に関する記述が、2つの独立した文に分割されました。これにより、それぞれのルールがより明確に伝わります。
  12. 関数値、チャネル値、マップ値の比較に関する表現の修正:

    • 関数値の比較について、「同じ関数を指す」から「同じ関数を参照する」に表現が変更されました。
    • チャネル値とマップ値の比較について、「同じ make の呼び出しによって作成された」から「同じ make への呼び出しによって作成された」に表現が変更されました。これらは意味的な変更ではなく、より自然な英語表現への修正です。
  13. インターフェース値の比較に関する詳細な説明の追加:

    • 重要な変更点の一つ: インターフェース値の比較に関する記述が大幅に明確化されました。
      • 変更前: 「インターフェース値は、同じ静的型を持つ場合、比較互換性があり、同じ動的型を持つ場合、等しい」
      • 変更後: 「インターフェース値は、同じ静的型を持つ場合、比較できる。それらは、同じ動的型を持ち、かつ基になる値が等しい場合にのみ等しい」
      • 背景: Goのインターフェース値は、内部的に「型」と「値」のペアとして表現されます。インターフェース値が比較可能であるためには、まずその「静的型」(インターフェース型自体)が同じである必要があります。そして、それらが「等しい」と判断されるためには、両方のインターフェース値が保持する「動的型」(基になる具体的な型)が同じであり、かつその「基になる値」自体も等しい必要があります。この修正は、インターフェースの比較におけるこれらの複雑なルールを正確に反映し、誤解を招かないようにしています。
  14. 理想型 (Ideal Type) の強調:

    • 「理想整数」や「理想浮動小数点」という用語を強調するために、引用符 (``) ではなくHTMLのイタリックタグ (<i>) が使用されるようになりました。これも、仕様書全体での用語の強調方法の統一を目的としています。

これらの変更は、Go言語の仕様書がより正確で、明確で、一貫性のあるものになるように、細部にわたる注意が払われたことを示しています。特に、インターフェースの代入と比較に関する修正は、Goの型システムの重要な側面を正確に記述するために不可欠でした。

コアとなるコードの変更箇所

このコミットは doc/go_spec.html ファイルのみを変更しています。以下に主要な変更箇所の差分を示します。

--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -188,10 +188,6 @@ The form <code>\"a ... b\"</code> represents the set of characters from
 <code>a</code> through <code>b</code> as alternatives.
 </p>
 
-<p>
-Where possible, recursive productions are used to express evaluation order
-and operator precedence syntactically.
-</p>
 <hr/>
 
 <h2>Source code representation</h2>
@@ -621,8 +617,9 @@ uintptr  smallest uint type large enough to store the uninterpreted
 </pre>
 
 <p>
-Except for <code>byte</code>, which is an alias for <code>uint8</code>,
-to avoid portability issues all numeric types are distinct. Conversions
+To avoid portability issues all numeric types are distinct except
+<code>byte</code>, which is an alias for <code>uint8</code>.
+Conversions
 are required when different numeric types are mixed in an expression
 or assignment. For instance, <code>int32</code> and <code>int</code>
 are not the same type even though they may have the same size on a 
@@ -669,7 +666,7 @@ StringLit   = string_lit { string_lit } .\
 <p>\
 A struct is a sequence of named\
 elements, called fields, with various types. A struct type declares\
-an identifier and type for each field. Within a struct field identifiers\
+an identifier and type for each field. Within a struct, field identifiers\
 must be unique and  field types must be complete (§Types).\
 </p>\
 
@@ -696,8 +693,8 @@ struct {\
 <p>\
 A field declared with a type but no field identifier is an <i>anonymous field</i>.\
 Such a field type must be specified as\
-a type name <code>T</code> or as a pointer to a type name <code>*T</code>\
-and <code>T</code> itself may not be\
+a type name <code>T</code> or as a pointer to a type name <code>*T</code>,\
+and <code>T</code> itself, may not be\
 a pointer or interface type. The unqualified type name acts as the field identifier.\
 </p>\
 
@@ -706,8 +703,8 @@ a pointer or interface type. The unqualified type name acts as the field identif\
 struct {\
  \tT1;        // the field name is T1\
  \t*T2;       // the field name is T2\
-\tP.T3;      // the field name is the unqualified type name T3\
-\t*P.T4;     // the field name is the unqualified type name T4\
+\tP.T3;      // the field name is T3\
+\t*P.T4;     // the field name is T4\
  \tx, y int;  \
 }\
 </pre>\
@@ -782,7 +779,7 @@ indices 0 through the <code>len(a)-1</code> (§Indexes).\
 \
 <p>\
 A pointer type denotes the set of all pointers to variables of a given\
-type, called the ``base type\'\' of the pointer.\
+type, called the <i>base type</i> of the pointer.\
 A pointer value may be <code>nil</code>.\
 </p>\
 
@@ -826,7 +823,7 @@ The types of parameters and results must be complete.\
 <p>\
 For the last parameter only, instead of a type one may write\
 <code>...</code> to indicate that the function may be invoked with\
-an arbitrary number (including zero) of additional arguments of any\
+zero or more additional arguments of any\
 type. If parameters of such a function are named, the final identifier\
 list must be a single name, that of the <code>...</code> parameter.\
 </p>\
@@ -995,7 +992,8 @@ and the relationship between <code>len()</code> and <code>cap()</code> is:\
 </pre>\
 \
 <p>\
-The value of an uninitialized slice is <code>nil</code>, and its length and capacity\
+The value of an uninitialized slice is <code>nil</code>.\
+The length and capacity of a <code>nil</code> slice\
 are 0. A new, initialized slice value for a given element type <code>T</code> is\
 made using the built-in function <code>make</code>, which takes a slice type\
 and parameters specifying the length and optionally the capacity:\
@@ -1020,7 +1018,7 @@ produces the same slice as allocating an array and slicing it:\
 </p>\
 \
 <pre>\
-make([capacity]T)[0 : length]\
+make([]T, capacity)[0 : length]\
 </pre>\
 \
 \
@@ -1062,20 +1060,27 @@ map [string] interface {}\
 The number of elements is called the length and is never negative.\
 The length of a map <code>m</code> can be discovered using the\
 built-in function <code>len(m)</code> and may change during execution.\
-The value of an uninitialized map is <code>nil</code>\
+The value of an uninitialized map is <code>nil</code>.\
 </p>\
 <p>\
 Upon creation, a map is empty.  Values may be added and removed\
 during execution using special forms of assignment (§Assignments).\
 A new, empty map value is made using the built-in\
 function <code>make</code>, which takes the map type and an optional\
-capacity, an allocation hint, as arguments:\
+capacity hint as arguments:\
 </p>\
 \
 <pre>\
-make(map[string] int, 100);\
+make(map[string] int)\
+make(map[string] int, 100)\
 </pre>\
 \
+<p>\
+The initial capacity does not bound its size:\
+maps grow to accommodate the number of items\
+stored in them.\
+</p>\
+\
 <h3>Channel types</h3>\
 \
 <p>\
@@ -1113,7 +1118,7 @@ which takes the channel type and an optional capacity as arguments:\
 </p>\
 \
 <pre>\
-make(chan int, 100);\
+make(chan int, 100)\
 </pre>\
 \
 <p>\
@@ -1130,7 +1135,7 @@ Types may be <i>different</i>, <i>structurally equal</i> (or just <i>equal</i>),\
 or <i>identical</i>.\
 Go is <i>type safe</i>: different types cannot be mixed\
 in binary operations and values cannot be assigned to variables of different\
-types. They can be assigned to variables of equal type.\
+types. Values can be assigned to variables of equal type.\
 </p>\
 \
 <h3>Type equality and identity </h3>\
@@ -1245,7 +1250,7 @@ When assigning to a slice variable, the array is not copied but a\
 slice comprising the entire array is created.\
 </li>\
 <li>\
-A value can be assigned to an interface variable if the dynamic\
+A value can be assigned to an interface variable if the static\
 type of the value implements the interface.\
 </li>\
 <li>\
@@ -1273,8 +1278,8 @@ compared for equality or inequality using the <code>==</code> and\
 Arrays and structs may not be compared to anything.\
 </li>\
 <li>\
-A slice value may only be compared explicitly against <code>nil</code>\
-and is equal to <code>nil</code> if it has been assigned the explicit\
+A slice value may only be compared explicitly against <code>nil</code>.\
+A slice value is equal to <code>nil</code> if it has been assigned the explicit\
 value <code>nil</code> or if it is a variable (or array element,\
 field, etc.) that has not been modified since it was created\
 uninitialized.\
@@ -1294,15 +1299,15 @@ unequal if one equals <code>nil</code> and one does not.\
 Pointer values are equal if they point to the same location.\
 </li>\
 <li>\
-Function values are equal if they point to the same function.\
+Function values are equal if they refer to the same function.\
 </li>\
 <li>\
-Channel and map values are equal if they were created by the same call of <code>make</code>\
+Channel and map values are equal if they were created by the same call to <code>make</code>\
 (§Making slices, maps, and channels).\
 </li>\
 <li>\
-Interface values are comparison compatible if they have the same static type and\
-equal if they have the same dynamic type.\
+Interface values may be compared if they have the same static type.\
+They will be equal only if they have the same dynamic type and the underlying values are equal.\
 </li>\
 </ul>\
 <hr/>\
@@ -1437,7 +1442,7 @@ CompleteType = Type .\
 <p>\
 If the type (CompleteType) is omitted, the constants take the\
 individual types of the corresponding expressions, which may be\
-``ideal integer\'\' or ``ideal float\'\' (§Ideal number).  If the type\
+<i>ideal integer</i> or <i>ideal float</i> (§Ideal number).  If the type\
 is present, all constants take the type specified, and the types\
 of all the expressions must be assignment-compatible\
 with that type.\

コアとなるコードの解説

このコミットにおけるコアとなるコードの変更は、Go言語の仕様書 doc/go_spec.html 内のテキストコンテンツの修正に集約されます。これらの変更は、Go言語の型システムに関する記述の正確性、明確性、および一貫性を向上させることを目的としています。

以下に、主要な変更点とその解説を詳述します。

  1. 評価順序と演算子優先順位に関する記述の削除:

    • 変更前: <p>Where possible, recursive productions are used to express evaluation order and operator precedence syntactically.</p>
    • 変更後: 削除
    • 解説: この段落は、Go言語の構文解析器の設計原則に関する一般的なコメントであり、言語仕様そのものの振る舞いを直接記述するものではありませんでした。仕様書をより簡潔にし、言語の機能とセマンティクスに焦点を当てるために削除されました。
  2. 数値型の区別に関する表現の修正:

    • 変更前: Except for <code>byte</code>, which is an alias for <code>uint8</code>, to avoid portability issues all numeric types are distinct.
    • 変更後: To avoid portability issues all numeric types are distinct except <code>byte</code>, which is an alias for <code>uint8</code>.
    • 解説: 文の構造を改善し、より自然な読みにするために語順が変更されました。意味的な内容は同じですが、読者にとって理解しやすくなっています。Goでは byteuint8 のエイリアスである点を除き、異なる数値型は厳密に区別され、明示的な型変換が必要です。
  3. 構造体フィールド識別子と匿名フィールドの記述の明確化:

    • 変更前: Within a struct field identifiers
    • 変更後: Within a struct, field identifiers
    • 解説: 文の途中にコンマを追加することで、読点の役割を果たし、文の構造を明確にしています。
    • 変更前: a type name <code>T</code> or as a pointer to a type name <code>*T</code> and <code>T</code> itself may not be
    • 変更後: a type name <code>T</code> or as a pointer to a type name <code>*T</code>, and <code>T</code> itself, may not be
    • 解説: 匿名フィールドの型に関する説明で、コンマを追加することで、条件の区切りを明確にし、読みやすさを向上させています。
    • 変更前: P.T3; // the field name is the unqualified type name T3
    • 変更後: P.T3; // the field name is T3
    • 解説: 匿名フィールドのコメントから「the unqualified type name」という冗長な表現を削除し、より簡潔で直接的な説明に修正しました。匿名フィールドの識別子がその非修飾型名であることは、Goの仕様上自明であるため、コメントを簡略化しています。
  4. ポインタの「基底型 (base type)」の強調:

    • 変更前: type, called the ``base type'' of the pointer.
    • 変更後: type, called the <i>base type</i> of the pointer.
    • 解説: 用語の強調方法をHTMLのイタリックタグ (<i>) に統一しました。これは、仕様書全体での表現の一貫性を保つための変更です。
  5. 可変長引数関数 (Variadic Functions) の表現の改善:

    • 変更前: an arbitrary number (including zero) of additional arguments of any
    • 変更後: zero or more additional arguments of any
    • 解説: 「任意の数(ゼロを含む)」という表現を「ゼロ個以上」というより簡潔で一般的な表現に修正しました。意味は同じですが、よりGoの慣用的な表現に近づいています。
  6. スライスの初期化と nil スライスの振る舞いの明確化:

    • 変更前: The value of an uninitialized slice is <code>nil</code>, and its length and capacity
    • 変更後: The value of an uninitialized slice is <code>nil</code>. The length and capacity of a <code>nil</code> slice
    • 解説: 1つの文を2つの文に分割することで、初期化されていないスライスが nil であることと、nil スライスの長さと容量が0であるという2つの事実をより明確に区別して記述しています。
    • 変更前: make([capacity]T)[0 : length]
    • 変更後: make([]T, capacity)[0 : length]
    • 解説: make 関数でスライスを生成する際の構文例を修正しました。make はスライス型 ([]T) を引数にとるため、[capacity]T ではなく []T が正しい表記です。これは、Goの組み込み関数の正確な使用法を示す重要な修正です。
  7. マップの初期化と容量に関する詳細の追加:

    • 変更前: The value of an uninitialized map is <code>nil</code>
    • 変更後: The value of an uninitialized map is <code>nil</code>.
    • 解説: 文末に句点を追加しました。
    • 変更前: make(map[string] int, 100);
    • 変更後: make(map[string] int)make(map[string] int, 100)
    • 解説: make 関数でマップを生成する際に、容量を指定しない形式と指定する形式の両方の例を示すことで、より包括的な情報を提供しています。
    • 追加: <p>The initial capacity does not bound its size: maps grow to accommodate the number of items stored in them.</p>
    • 解説: マップの初期容量がそのサイズの上限ではないことを明確にする新しい段落が追加されました。これは、Goのマップが動的に拡張される性質を持つことを強調し、make で指定する容量が単なるパフォーマンスヒントであることを読者に理解させるための重要な情報です。
  8. チャネルの make 関数の例の修正:

    • 変更前: make(chan int, 100);
    • 変更後: make(chan int, 100)
    • 解説: Goのコード例では通常セミコロンは不要であるため、末尾のセミコロンが削除されました。
  9. 型の代入に関する表現の修正:

    • 変更前: They can be assigned to variables of equal type.
    • 変更後: Values can be assigned to variables of equal type.
    • 解説: 代入の主体が「型」ではなく「値」であることを明確にするために、「They」を「Values」に修正しました。
  10. インターフェースへの代入における「静的型」の修正:

    • 変更前: A value can be assigned to an interface variable if the dynamic type of the value implements the interface.
    • 変更後: A value can be assigned to an interface variable if the static type of the value implements the interface.
    • 解説: これは非常に重要な修正です。Goにおいて、インターフェースへの代入の可否は、コンパイル時に値の「静的型」(宣言された型)がインターフェースのメソッドセットを実装しているかどうかによって決定されます。実行時の「動的型」(実際に保持している具体的な型)は、代入の可否には直接関係ありません。この修正は、Goの型システムの厳密なルールを正確に反映しています。
  11. スライスの比較に関する明確化:

    • 変更前: A slice value may only be compared explicitly against <code>nil</code> and is equal to <code>nil</code> if it has been assigned the explicit
    • 変更後: A slice value may only be compared explicitly against <code>nil</code>. A slice value is equal to <code>nil</code> if it has been assigned the explicit
    • 解説: 1つの文を2つの文に分割することで、スライスが nil とのみ比較できるというルールと、nil スライスの条件をより明確に区別して記述しています。
  12. 関数値、チャネル値、マップ値の比較に関する表現の修正:

    • 変更前: Function values are equal if they point to the same function.
    • 変更後: Function values are equal if they refer to the same function.
    • 解説: 「point to」を「refer to」に変更することで、より一般的な「参照」という概念を表現しています。
    • 変更前: Channel and map values are equal if they were created by the same call of <code>make</code>
    • 変更後: Channel and map values are equal if they were created by the same call to <code>make</code>
    • 解説: 「call of」を「call to」に変更することで、より自然な英語表現に修正しています。
  13. インターフェース値の比較に関する詳細な説明の追加:

    • 変更前: Interface values are comparison compatible if they have the same static type and equal if they have the same dynamic type.
    • 変更後: Interface values may be compared if they have the same static type. They will be equal only if they have the same dynamic type and the underlying values are equal.
    • 解説: この修正は、インターフェース値の比較ルールを大幅に明確化しています。
      • まず、インターフェース値が「比較可能 (may be compared)」であるためには、それらが同じ「静的型」(同じインターフェース型)を持つ必要があることを明確にしています。
      • 次に、インターフェース値が「等しい (equal)」と判断されるための条件を厳密に定義しています。それは、両方のインターフェース値が保持する「動的型」(基になる具体的な型)が同じであり、かつその「基になる値」自体も等しい場合に限られる、というものです。
      • この詳細な説明は、Goのインターフェースの内部表現(型と値のペア)と、それらの比較セマンティクスを正確に反映しており、読者の誤解を防ぐ上で非常に重要です。
  14. 理想型 (Ideal Type) の強調:

    • 変更前: ```ideal integer'' or ``ideal float''`
    • 変更後: <i>ideal integer</i> or <i>ideal float</i>
    • 解説: 用語の強調方法をHTMLのイタリックタグ (<i>) に統一しました。

これらの変更は、Go言語の仕様書が、言語の振る舞いをより正確かつ明確に記述するための継続的な努力の一環として行われたものです。特に、型システム、スライス、マップ、インターフェースといったGoの重要な概念に関する記述の精度向上は、言語の理解を深める上で不可欠です。

関連リンク

  • Go言語公式ウェブサイト: https://go.dev/
  • Go言語仕様書: https://go.dev/ref/spec (このコミットが修正したドキュメントの最新版)
  • A Tour of Go: https://go.dev/tour/ (Go言語の基本的な概念を学ぶためのインタラクティブなチュートリアル)

参考にした情報源リンク

  • GitHub上のコミットページ: https://github.com/golang/go/commit/da38974c8851c06868c8d941db5aa6d44e023524
  • Go言語仕様書 (当時のバージョン): doc/go_spec.html (コミットに含まれるファイル)
  • Go言語の型システムに関する一般的な知識
  • Go言語のスライス、マップ、インターフェースに関する一般的な知識
  • Go言語の make 関数に関する一般的な知識
  • Go言語の可変長引数関数に関する一般的な知識