[インデックス 12598] ファイルの概要
このコミットは、Go言語の公式仕様書 doc/go_spec.html
における型同一性 (type identity) の定義に関する不正確さを修正するものです。具体的には、名前付き型 (named types) の同一性を定義する際に参照される概念を「宣言 (declaration)」から「型仕様 (TypeSpec)」へと変更しています。これにより、Go言語の型システムにおける型同一性の厳密な定義がより正確に反映されるようになります。
コミット
commit 82fc28c0f5a5af9fd18c0c49a65aa6a44ede1aa3
Author: Robert Griesemer <gri@golang.org>
Date: Mon Mar 12 20:27:27 2012 -0700
go spec: fix inaccuracy in type identity definition
Pointed out by Steven Blenkinsop (steven099@gmail.com)
via golang-nuts.
R=r, dsymonds
CC=golang-dev
https://golang.org/cl/5783087
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/82fc28c0f5a5af9fd18c0c49a65aa6a44ede1aa3
元コミット内容
このコミットは、Go言語の仕様書 doc/go_spec.html
の以下の箇所を修正しています。
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,6 +1,6 @@
<!--{
"Title": "The Go Programming Language Specification",
- "Subtitle": "Version of March 7, 2012",
+ "Subtitle": "Version of March 12, 2012",
"Path": "/ref/spec"
}-->
@@ -1321,7 +1321,7 @@ Two types are either <i>identical</i> or <i>different</i>.
<p>
Two named types are identical if their type names originate in the same
-type <a href=\"#Declarations_and_scope\">declaration</a>.
+<a href=\"#Type_declarations\">TypeSpec</a>.
A named and an unnamed type are always different. Two unnamed types are identical
if the corresponding type literals are identical, that is, if they have the same
literal structure and corresponding components have identical types. In detail:
主な変更点は、Go言語仕様書の「型同一性 (Type identity)」のセクションにおいて、名前付き型の同一性を定義する際の記述を「同じ型宣言 (declaration) から派生している場合」から「同じ型仕様 (TypeSpec) から派生している場合」へと変更した点です。また、仕様書のバージョン日付も更新されています。
変更の背景
この変更は、Steven Blenkinsop氏が golang-nuts
メーリングリストで指摘した、Go言語仕様書における型同一性定義の不正確さを修正するために行われました。Go言語の型システムにおいて、型同一性は非常に重要な概念であり、コンパイラが型の互換性を判断する際の基礎となります。
Go言語では、型は「宣言 (declaration)」によって導入されますが、特に型定義 (type definition) の文脈では、その型の構造を記述する部分を「型仕様 (TypeSpec)」と呼びます。既存の仕様書では、名前付き型の同一性を「同じ型宣言から派生している」と記述していましたが、これは特定のケースにおいて誤解を招く可能性がありました。例えば、異なるパッケージで同じ名前の型が宣言された場合、それらは異なる型ですが、「宣言」という言葉だけではその区別が曖昧になることがありました。
この修正は、型同一性の定義をより厳密にし、Go言語のコンパイラが実際にどのように型を比較しているかという実装の詳細と、仕様書上の記述との間の乖離をなくすことを目的としています。これにより、Go言語の型システムに関する理解が深まり、より正確なプログラミングが可能になります。
前提知識の解説
このコミットを理解するためには、以下のGo言語の基本的な概念を理解しておく必要があります。
-
型 (Types): Go言語におけるデータ型は、値が取りうる値の集合と、その値に対して実行できる操作を定義します。Goには、
int
,string
,bool
などの組み込み型と、ユーザーが定義できる複合型(struct
,array
,slice
,map
,interface
,channel
,function
など)があります。 -
名前付き型 (Named Types) と無名型 (Unnamed Types):
- 名前付き型:
type MyInt int
のようにtype
キーワードを使って明示的に名前が付けられた型です。int
,string
などの組み込み型も名前付き型です。 - 無名型:
[]int
(スライス),map[string]int
(マップ),struct { X int; Y int }
(構造体) のように、明示的な名前を持たない型です。これらは型リテラル (type literal) によって直接記述されます。
- 名前付き型:
-
型宣言 (Type Declaration): Go言語において、新しい名前付き型を導入するための構文です。
type MyType UnderlyingType
ここで
MyType
は新しい名前付き型、UnderlyingType
はその基底となる型(組み込み型、複合型、または別の名前付き型)です。 -
型仕様 (TypeSpec): 型宣言の一部であり、新しい型の構造を定義する部分を指します。例えば、
type MyStruct struct { Field int }
という宣言において、struct { Field int }
の部分が型仕様です。これは、無名型を記述する型リテラルと密接に関連しています。 -
型同一性 (Type Identity): Go言語において、2つの型が「同じ」であると見なされるかどうかのルールです。これは、変数への代入、関数の引数、比較演算など、多くの場面でコンパイラによってチェックされます。Go言語の型同一性のルールは比較的厳格です。
- 名前付き型の場合: 2つの名前付き型は、それらが同じ型宣言から派生している場合にのみ同一と見なされます。
- 無名型の場合: 2つの無名型は、それらが同じリテラル構造を持ち、かつ対応するコンポーネント(配列の要素型、構造体のフィールドの型、関数の引数と戻り値の型など)が同一である場合にのみ同一と見なされます。
技術的詳細
このコミットの核心は、Go言語仕様書における「型同一性」の定義の微調整です。特に、名前付き型の同一性に関する記述が変更されています。
変更前: 「2つの名前付き型は、それらの型名が同じ型宣言 (declaration) から派生している場合に同一である。」
変更後: 「2つの名前付き型は、それらの型名が同じ型仕様 (TypeSpec) から派生している場合に同一である。」
この変更は、一見すると些細に見えますが、Go言語の型システムの厳密な理解において重要な意味を持ちます。
Go言語の仕様では、型宣言は以下のように定義されています。
TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) .
TypeSpec = Identifier Type .
ここで Type
は、型リテラル(無名型を記述する構文)または既存の名前付き型への参照です。
例えば、以下のコードを考えます。
package main
type MyInt int
func main() {
type AnotherInt int // これは別の型宣言
var a MyInt
var b AnotherInt
// a = b // コンパイルエラー: cannot use b (type AnotherInt) as type MyInt in assignment
}
この場合、MyInt
と AnotherInt
は異なる型です。これらは異なる TypeSpec
から派生しています。
また、以下のケースを考えます。
package p1
type T struct { x int }
package p2
type T struct { x int }
p1.T
と p2.T
は、どちらも struct { x int }
という同じ型リテラル(型仕様)を持っていますが、異なるパッケージで宣言されているため、異なる名前付き型です。これらは異なる TypeSpec
から派生しているため、同一ではありません。
「宣言 (declaration)」という言葉は、型が導入される文脈全体を指すことがありますが、「型仕様 (TypeSpec)」は、その型の具体的な構造を定義する部分に焦点を当てています。Go言語の型同一性のルールは、特に名前付き型の場合、その型の「起源」に厳密に基づいています。同じ TypeSpec
から派生しているということは、その型が言語仕様上、同じ定義を持つことを意味します。
この修正は、Go言語の型システムが、単に型名が同じであるか、あるいは基底型が同じであるかだけでなく、その型がどの TypeSpec
によって定義されたかという「同一性」を重視していることを明確にしています。これにより、コンパイラが型チェックを行う際の内部的なロジックと、仕様書上の記述がより密接に一致するようになります。
コアとなるコードの変更箇所
変更は doc/go_spec.html
ファイルの以下の行に集中しています。
<p>
Two named types are identical if their type names originate in the same
-type <a href=\"#Declarations_and_scope\">declaration</a>.
+<a href=\"#Type_declarations\">TypeSpec</a>.
この変更により、declaration
へのリンクが TypeSpec
へのリンクに置き換えられ、テキストもそれに合わせて修正されています。
また、仕様書のバージョン日付も更新されています。
- "Subtitle": "Version of March 7, 2012",
+ "Subtitle": "Version of March 12, 2012",
コアとなるコードの解説
変更されたHTMLスニペットは、Go言語仕様書の「型同一性 (Type identity)」セクションの一部です。
元の記述:
Two named types are identical if their type names originate in the same type <a href="#Declarations_and_scope">declaration</a>.
(2つの名前付き型は、それらの型名が同じ型宣言から派生している場合に同一である。)
修正後の記述:
Two named types are identical if their type names originate in the same <a href="#Type_declarations">TypeSpec</a>.
(2つの名前付き型は、それらの型名が同じ型仕様から派生している場合に同一である。)
この変更は、型同一性の定義における「起源」の概念をより正確にしています。Go言語では、型宣言は新しい名前付き型を導入する文全体を指しますが、TypeSpec
はその宣言の中で実際に型の構造を定義する部分を指します。
例えば、type MyStruct struct { Field int }
という型宣言があった場合、struct { Field int }
の部分が TypeSpec
に該当します。Go言語の型同一性ルールでは、この TypeSpec
が同じであるかどうかが、名前付き型の同一性を判断する際の決定的な要素となります。異なるパッケージで同じ名前の型が宣言されたり、同じパッケージ内でも異なる型宣言によって同じ構造の型が導入されたりする場合、それらは異なる TypeSpec
から派生しているため、異なる型と見なされます。
この修正により、Go言語の型システムがどのように型を区別し、同一性を判断しているかという、より深いレベルの正確な情報が仕様書に反映されました。これは、Go言語のコンパイラの実装と、言語仕様との整合性を高めるための重要な改善です。
関連リンク
- Go言語仕様書: https://go.dev/ref/spec (このコミットが修正したドキュメントの最新版)
- Go言語の型同一性に関する議論 (golang-nutsメーリングリストなど): このコミットの背景となった具体的な議論のスレッドは、時間が経過しているため特定が難しい場合がありますが、
golang-nuts
はGo言語の設計や仕様に関する活発な議論が行われる場です。
参考にした情報源リンク
- Go言語の公式ドキュメントと仕様書
- Go言語の型システムに関する一般的な解説
- Go言語のソースコードリポジトリ (特に
doc/go_spec.html
の変更履歴) - コミットメッセージに記載されている
https://golang.org/cl/5783087
(GoのChange Listへのリンク。現在はリダイレクトされる可能性がありますが、当時の変更の詳細が確認できる可能性があります。) - Go言語の型同一性に関するブログ記事やチュートリアル (一般的な理解を深めるため)
- Steven Blenkinsop氏の指摘に関する
golang-nuts
メーリングリストのアーカイブ (もし特定できれば)