[インデックス 1042] ファイルの概要
このコミットは、Go言語のreflect
パッケージ内のvalue.go
ファイルに対する変更です。具体的には、CommonV
という構造体の名前をCommon
に変更し、それに伴う参照箇所の修正を行っています。この変更は、以前の6g
コンパイラにおける特定の制約(バグまたは設計上の問題)に対する回避策が不要になったことを示しています。
コミット
commit bcd6403cc9f64a7a04297b9cac891ffe96a5dd0e
Author: Russ Cox <rsc@golang.org>
Date: Mon Nov 3 16:00:08 2008 -0800
remove unnecessary 6g workaround
R=r
DELTA=51 (0 added, 0 deleted, 51 changed)
OCL=18399
CL=18402
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/bcd6403cc9f64a7a04297b9cac891ffe96a5dd0e
元コミット内容
このコミットの元々の内容は、「不要な6gの回避策を削除する」というものです。これは、Go言語の初期のコンパイラである6g
に関連する特定のコード上の制約が解消されたため、その制約に対応するために導入されていたコードを元に戻すことを意味します。
変更の背景
この変更の背景には、Go言語の初期のコンパイラである6g
の挙動が関係しています。コミット前のsrc/lib/reflect/value.go
のCommonV
構造体の定義には、// BUG: want to call this Common but 6g does not hide the name
というコメントがありました。これは、開発者が本来Common
という名前を使いたかったにもかかわらず、6g
コンパイラがその名前を適切に扱えない(おそらく名前の衝突やスコープの問題)ために、一時的にCommonV
という回避策の名前を使用していたことを示唆しています。
このコミットが行われた2008年11月時点では、Go言語はまだ開発の初期段階にあり、コンパイラやツールチェインも活発に改善されていました。このコミットは、6g
コンパイラのバグが修正されたか、あるいはその制約がなくなったため、本来意図していたCommon
という名前に戻すことが可能になったことを示しています。これにより、コードの可読性と意図が明確になります。
前提知識の解説
- Go言語の
reflect
パッケージ:reflect
パッケージは、Goプログラムが実行時に自身の構造を検査(リフレクション)できるようにする機能を提供します。これにより、型情報、フィールド、メソッドなどを動的に操作することが可能になります。このパッケージは、例えばJSONエンコーダ/デコーダやORM(Object-Relational Mapping)などの汎用的なライブラリを実装する際に不可欠です。 6g
コンパイラ:6g
は、Go言語の初期のコンパイラの一つです。Go言語の初期には、ターゲットアーキテクチャごとに異なるコンパイラが存在しました。例えば、6g
はamd64アーキテクチャ向け、8g
は386アーキテクチャ向け、5g
はARMアーキテクチャ向けでした。これらのコンパイラは、Go言語のソースコードを機械語に変換する役割を担っていました。開発の初期段階では、これらのコンパイラには様々なバグや未実装の機能が存在し、それらに対する回避策がコードベースに散見されることがありました。- 構造体(Struct): Go言語における構造体は、異なる型のフィールドをまとめた複合データ型です。オブジェクト指向プログラミングにおけるクラスの概念に似ていますが、メソッドは構造体自体ではなく、その構造体の型に紐付けられます。
- 名前の衝突とスコープ: プログラミングにおいて、同じ名前が異なる文脈で定義されると、名前の衝突が発生する可能性があります。コンパイラは、変数のスコープ(有効範囲)を管理し、どの名前がどの定義を参照しているかを解決します。初期のコンパイラでは、この名前解決のロジックにバグが含まれることがありました。
技術的詳細
このコミットの技術的な核心は、Go言語のreflect
パッケージにおける内部構造体の命名規則の修正です。
reflect
パッケージは、Goの型システムをプログラムから操作するための基盤を提供します。Value
インターフェースは、Goのあらゆる値(整数、文字列、構造体、関数など)を抽象的に表現するためのものです。このValue
インターフェースを実装する具体的な型(IntValueStruct
, StringValueStruct
など)は、それぞれが共通の基盤となる情報を保持する必要があります。
コミット前のコードでは、この共通の基盤情報を持つ構造体がCommonV
と命名されていました。これは、// BUG: want to call this Common but 6g does not hide the name
というコメントが示すように、6g
コンパイラの特定の制約を回避するための命名でした。この制約は、おそらくCommon
という名前がGo言語の予約語や、コンパイラ内部で特殊な意味を持つ名前と衝突していたか、あるいは特定のスコープ内でCommon
という名前が正しく解決されなかったことに起因すると考えられます。
このコミットでは、その6g
コンパイラの制約が解消されたため、CommonV
を本来意図していたCommon
にリネームしています。これにより、コードはより直感的になり、reflect
パッケージの内部構造がより明確になります。
具体的には、以下の変更が行われています。
type CommonV struct { ... }
がtype Common struct { ... }
に変更。func (c *CommonV) Kind() int { ... }
がfunc (c *Common) Kind() int { ... }
に変更。func (c *CommonV) Type() Type { ... }
がfunc (c *Common) Type() Type { ... }
に変更。MissingValueStruct
,IntValueStruct
など、CommonV
を埋め込みフィールドとして持っていた全ての構造体で、CommonV
がCommon
に置き換えられています。MissingCreator
,IntCreator
などのファクトリ関数で、CommonV{...}
のインスタンス生成がCommon{...}
に変更されています。
この変更は、Go言語のコンパイラと標準ライブラリが成熟していく過程で、初期の設計上の妥協点やコンパイラのバグが解消されていく典型的な例と言えます。
コアとなるコードの変更箇所
変更はsrc/lib/reflect/value.go
ファイルのみで行われています。
--- a/src/lib/reflect/value.go
+++ b/src/lib/reflect/value.go
@@ -21,17 +21,17 @@ export type Value interface {
// Common fields and functionality for all values
-type CommonV struct { // BUG: want to call this Common but 6g does not hide the name
+type Common struct {
kind int;
typ Type;
addr Addr;
}
-func (c *CommonV) Kind() int {
+func (c *Common) Kind() int {
return c.kind
}
-func (c *CommonV) Type() Type {
+func (c *Common) Type() Type {
return c.typ
}
@@ -68,11 +68,11 @@ export type MissingValue interface {
}
type MissingValueStruct struct {
- CommonV
+ Common
}
func MissingCreator(typ Type, addr Addr) Value {
- return &MissingValueStruct{ CommonV{IntKind, typ, addr} }
+ return &MissingValueStruct{ Common{IntKind, typ, addr} }
}
// -- Int
@@ -85,11 +85,11 @@ export type IntValue interface {
}
type IntValueStruct struct {
- CommonV
+ Common
}
func IntCreator(typ Type, addr Addr) Value {
- return &IntValueStruct{ CommonV{IntKind, typ, addr} }
+ return &IntValueStruct{ Common{IntKind, typ, addr} }
}
func (v *IntValueStruct) Get() int {
@@ -110,11 +110,11 @@ export type Int8Value interface {
}
type Int8ValueStruct struct {
- CommonV
+ Common
}
func Int8Creator(typ Type, addr Addr) Value {
- return &Int8ValueStruct{ CommonV{Int8Kind, typ, addr} }
+ return &Int8ValueStruct{ Common{Int8Kind, typ, addr} }
}
func (v *Int8ValueStruct) Get() int8 {
@@ -135,11 +135,11 @@ export type Int16Value interface {
}
type Int16ValueStruct struct {
- CommonV
+ Common
}
func Int16Creator(typ Type, addr Addr) Value {
- return &Int16ValueStruct{ CommonV{Int16Kind, typ, addr} }
+ return &Int16ValueStruct{ Common{Int16Kind, typ, addr} }
}
func (v *Int16ValueStruct) Get() int16 {
@@ -160,11 +160,11 @@ export type Int32Value interface {\n }\n \n type Int32ValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func Int32Creator(typ Type, addr Addr) Value {\n-\treturn &Int32ValueStruct{ CommonV{Int32Kind, typ, addr} }\n+\treturn &Int32ValueStruct{ Common{Int32Kind, typ, addr} }\n }\n \n func (v *Int32ValueStruct) Get() int32 {\n@@ -185,11 +185,11 @@ export type Int64Value interface {\n }\n \n type Int64ValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func Int64Creator(typ Type, addr Addr) Value {\n-\treturn &Int64ValueStruct{ CommonV{Int64Kind, typ, addr} }\n+\treturn &Int64ValueStruct{ Common{Int64Kind, typ, addr} }\n }\n \n func (v *Int64ValueStruct) Get() int64 {\n@@ -210,11 +210,11 @@ export type UintValue interface {\n }\n \n type UintValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func UintCreator(typ Type, addr Addr) Value {\n-\treturn &UintValueStruct{ CommonV{UintKind, typ, addr} }\n+\treturn &UintValueStruct{ Common{UintKind, typ, addr} }\n }\n \n func (v *UintValueStruct) Get() uint {\n@@ -235,11 +235,11 @@ export type Uint8Value interface {\n }\n \n type Uint8ValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func Uint8Creator(typ Type, addr Addr) Value {\n-\treturn &Uint8ValueStruct{ CommonV{Uint8Kind, typ, addr} }\n+\treturn &Uint8ValueStruct{ Common{Uint8Kind, typ, addr} }\n }\n \n func (v *Uint8ValueStruct) Get() uint8 {\n@@ -260,11 +260,11 @@ export type Uint16Value interface {\n }\n \n type Uint16ValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func Uint16Creator(typ Type, addr Addr) Value {\n-\treturn &Uint16ValueStruct{ CommonV{Uint16Kind, typ, addr} }\n+\treturn &Uint16ValueStruct{ Common{Uint16Kind, typ, addr} }\n }\n \n func (v *Uint16ValueStruct) Get() uint16 {\n@@ -285,11 +285,11 @@ export type Uint32Value interface {\n }\n \n type Uint32ValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func Uint32Creator(typ Type, addr Addr) Value {\n-\treturn &Uint32ValueStruct{ CommonV{Uint32Kind, typ, addr} }\n+\treturn &Uint32ValueStruct{ Common{Uint32Kind, typ, addr} }\n }\n \n func (v *Uint32ValueStruct) Get() uint32 {\n@@ -310,11 +310,11 @@ export type Uint64Value interface {\n }\n \n type Uint64ValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func Uint64Creator(typ Type, addr Addr) Value {\n-\treturn &Uint64ValueStruct{ CommonV{Uint64Kind, typ, addr} }\n+\treturn &Uint64ValueStruct{ Common{Uint64Kind, typ, addr} }\n }\n \n func (v *Uint64ValueStruct) Get() uint64 {\n@@ -335,11 +335,11 @@ export type FloatValue interface {\n }\n \n type FloatValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func FloatCreator(typ Type, addr Addr) Value {\n-\treturn &FloatValueStruct{ CommonV{FloatKind, typ, addr} }\n+\treturn &FloatValueStruct{ Common{FloatKind, typ, addr} }\n }\n \n func (v *FloatValueStruct) Get() float {\n@@ -360,11 +360,11 @@ export type Float32Value interface {\n }\n \n type Float32ValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func Float32Creator(typ Type, addr Addr) Value {\n-\treturn &Float32ValueStruct{ CommonV{Float32Kind, typ, addr} }\n+\treturn &Float32ValueStruct{ Common{Float32Kind, typ, addr} }\n }\n \n func (v *Float32ValueStruct) Get() float32 {\n@@ -385,11 +385,11 @@ export type Float64Value interface {\n }\n \n type Float64ValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func Float64Creator(typ Type, addr Addr) Value {\n-\treturn &Float64ValueStruct{ CommonV{Float64Kind, typ, addr} }\n+\treturn &Float64ValueStruct{ Common{Float64Kind, typ, addr} }\n }\n \n func (v *Float64ValueStruct) Get() float64 {\n@@ -410,11 +410,11 @@ export type Float80Value interface {\n }\n \n type Float80ValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func Float80Creator(typ Type, addr Addr) Value {\n-\treturn &Float80ValueStruct{ CommonV{Float80Kind, typ, addr} }\n+\treturn &Float80ValueStruct{ Common{Float80Kind, typ, addr} }\n }\n \n /*\n@@ -439,11 +439,11 @@ export type StringValue interface {\n }\n \n type StringValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func StringCreator(typ Type, addr Addr) Value {\n-\treturn &StringValueStruct{ CommonV{StringKind, typ, addr} }\n+\treturn &StringValueStruct{ Common{StringKind, typ, addr} }\n }\n \n func (v *StringValueStruct) Get() string {\n@@ -464,11 +464,11 @@ export type BoolValue interface {\n }\n \n type BoolValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func BoolCreator(typ Type, addr Addr) Value {\n-\treturn &BoolValueStruct{ CommonV{BoolKind, typ, addr} }\n+\treturn &BoolValueStruct{ Common{BoolKind, typ, addr} }\n }\n \n func (v *BoolValueStruct) Get() bool {\n@@ -489,7 +489,7 @@ export type PtrValue interface {\n }\n \n type PtrValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func (v *PtrValueStruct) Get() Addr {\n@@ -501,7 +501,7 @@ func (v *PtrValueStruct) Sub() Value {\n }\n \n func PtrCreator(typ Type, addr Addr) Value {\n-\treturn &PtrValueStruct{ CommonV{PtrKind, typ, addr} };\n+\treturn &PtrValueStruct{ Common{PtrKind, typ, addr} };\n }\n \n // -- Array\n@@ -515,7 +515,7 @@ export type ArrayValue interface {\n }\n \n type OpenArrayValueStruct struct {\n-\tCommonV;\n+\tCommon;\n \telemtype\tType;\n \telemsize\tuint64;\n }\n@@ -542,7 +542,7 @@ func (v *OpenArrayValueStruct) Elem(i uint64) Value {\n }\n \n type FixedArrayValueStruct struct {\n-\tCommonV;\n+\tCommon;\n \telemtype\tType;\n \telemsize\tuint64;\n \tlen\tuint64;\n@@ -592,11 +592,11 @@ export type MapValue interface {\n }\n \n type MapValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func MapCreator(typ Type, addr Addr) Value {\n-\treturn &MapValueStruct{ CommonV{MapKind, typ, addr} }\n+\treturn &MapValueStruct{ Common{MapKind, typ, addr} }\n }\n \n func (v *MapValueStruct) Len() int {\n@@ -616,11 +616,11 @@ export type ChanValue interface {\n }\n \n type ChanValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func ChanCreator(typ Type, addr Addr) Value {\n-\treturn &ChanValueStruct{ CommonV{ChanKind, typ, addr} }\n+\treturn &ChanValueStruct{ Common{ChanKind, typ, addr} }\n }\n \n // -- Struct\n@@ -633,7 +633,7 @@ export type StructValue interface {\n }\n \n type StructValueStruct struct {\n-\tCommonV;\n+\tCommon;\n \tfield\t*[]Value;\n }\n \n@@ -648,7 +648,7 @@ func (v *StructValueStruct) Field(i int) Value {\n func StructCreator(typ Type, addr Addr) Value {\n \tt := typ.(StructType);\n \tnfield := t.Len();\n-\tv := &StructValueStruct{ CommonV{StructKind, typ, addr}, new([]Value, nfield) };\n+\tv := &StructValueStruct{ Common{StructKind, typ, addr}, new([]Value, nfield) };\n \tfor i := 0; i < nfield; i++ {\n \t\tname, ftype, str, offset := t.Field(i);\n \t\tv.field[i] = NewValueAddr(ftype, addr + offset);\n@@ -665,11 +665,11 @@ export type InterfaceValue interface {\n }\n \n type InterfaceValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func InterfaceCreator(typ Type, addr Addr) Value {\n-\treturn &InterfaceValueStruct{ CommonV{InterfaceKind, typ, addr} }\n+\treturn &InterfaceValueStruct{ Common{InterfaceKind, typ, addr} }\n }\n \n // -- Func\n@@ -680,11 +680,11 @@ export type FuncValue interface {\n }\n \n type FuncValueStruct struct {\n-\tCommonV\n+\tCommon\n }\n \n func FuncCreator(typ Type, addr Addr) Value {\n-\treturn &FuncValueStruct{ CommonV{FuncKind, typ, addr} }\n+\treturn &FuncValueStruct{ Common{FuncKind, typ, addr} }\n }\n \n var creator *map[int] Creator\n```
## コアとなるコードの解説
このコミットの主要な変更は、`src/lib/reflect/value.go`ファイル内で、`CommonV`という名前の構造体とその全ての参照を`Common`という名前に変更したことです。
* **`CommonV`から`Common`へのリネーム**:
`CommonV`構造体は、`reflect`パッケージ内で様々な`Value`インターフェースの実装(例: `IntValueStruct`, `StringValueStruct`など)が共通して持つべきフィールド(`kind`, `typ`, `addr`)を定義していました。この構造体は、Goの埋め込みフィールドの機能を使って、他の構造体に共通のプロパティを「継承」させるような形で利用されていました。
元のコードには`// BUG: want to call this Common but 6g does not hide the name`というコメントがあり、これは`6g`コンパイラが`Common`という名前を適切に扱えないというバグまたは制約があったため、一時的に`CommonV`という名前を使用していたことを示しています。このコミットは、その制約が解消されたため、本来意図していた`Common`という名前に戻すものです。
* **メソッドレシーバの変更**:
`CommonV`構造体に紐付けられていたメソッド(`Kind()`, `Type()`)のレシーバも、`*CommonV`から`*Common`に変更されています。これにより、新しい`Common`構造体を通じてこれらのメソッドが引き続き呼び出せるようになります。
* **構造体埋め込みフィールドの変更**:
`MissingValueStruct`, `IntValueStruct`, `UintValueStruct`など、`reflect`パッケージ内の多くの具体的な`Value`実装構造体は、`CommonV`を埋め込みフィールドとして持っていました。この変更により、これらの構造体も`CommonV`の代わりに`Common`を埋め込むように修正されています。
* **ファクトリ関数の変更**:
`MissingCreator`, `IntCreator`などの、各種`Value`インターフェースの実装を生成するファクトリ関数も、`CommonV{...}`の代わりに`Common{...}`を使用してインスタンスを生成するように変更されています。
この一連の変更は、コードのセマンティクス(意味)を変えるものではなく、コンパイラの制約が解消されたことによるコードのクリーンアップと、本来意図された命名への回帰を目的としています。これにより、`reflect`パッケージの内部構造がより自然で理解しやすくなりました。
## 関連リンク
* Go言語の`reflect`パッケージに関する公式ドキュメント: [https://pkg.go.dev/reflect](https://pkg.go.dev/reflect)
* Go言語の初期のコンパイラに関する情報(`6g`など)は、Goの歴史に関する資料や初期のメーリングリストの議論などで見つけることができます。
## 参考にした情報源リンク
* Go言語の公式ドキュメント
* Go言語のGitHubリポジトリのコミット履歴
* Go言語の初期のコンパイラに関する一般的な知識
* Web検索(`golang 6g compiler`などで検索し、初期のGo言語のコンパイラに関する情報を確認しました。)
* 例: [https://go.dev/doc/install/source](https://go.dev/doc/install/source) (Goの初期のビルドプロセスに関する記述で`6g`などのコンパイラ名が言及されていることがあります)
* Go言語のメーリングリストや初期の設計ドキュメントなども参考になる場合があります。