[インデックス 10023] ファイルの概要
このコミットは、Go言語のマップ(map)から要素を削除する機能の重要な進化を示すものです。Russ Coxによる2011年10月18日のコミットで、新しいdelete(m, x)
関数の導入と、従来のm[x] = 0, false
構文の廃止準備を行いました。
コミット
コミットハッシュ: 1d687c742ddad0be83314019c03e17bad7235535
作成者: Russ Cox rsc@golang.org
日付: 2011年10月18日 09:41:32 -0400
コミットメッセージ: gc: add delete(m, x) but leave in m[x] = 0, false.
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/1d687c742ddad0be83314019c03e17bad7235535
元コミット内容
gc: add delete(m, x) but leave in m[x] = 0, false.
The old m[x] = 0, false syntax will be deleted
in a month or so, once people have had time to
change their code (there is a gofix in a separate CL).
R=ken2
CC=golang-dev
https://golang.org/cl/5265048
変更されたファイル:
- src/cmd/gc/builtin.c.boot (1行追加)
- src/cmd/gc/go.h (4行追加, 1行削除)
- src/cmd/gc/lex.c (1行追加)
- src/cmd/gc/runtime.go (1行追加)
- src/cmd/gc/subr.c (1行追加)
- src/cmd/gc/typecheck.c (37行追加, 3行削除)
- src/cmd/gc/walk.c (31行追加)
- src/pkg/runtime/hashmap.c (22行追加)
合計: 8ファイル、94行追加、4行削除
変更の背景
このコミットは、Go 1.0リリース(2012年3月)に向けた言語仕様の最終化の一環として実施されました。2011年当時、Goはまだ実験的な段階にあり、言語の設計に関する重要な決定が行われていました。
マップからの要素削除に関して、従来のm[x] = 0, false
構文は以下の問題を抱えていました:
- 直感的でない構文: 削除操作であることが明確でない
- 型安全性の問題: 第一引数の値は無視されるが、型チェックが必要
- 一貫性の欠如: 他の組み込み操作と構文が異なる
- コミュニティからの懸念: 開発者コミュニティから批判的な意見が寄せられていた
前提知識の解説
Go言語のマップ(Map)
Go言語のマップは、キーと値のペアを格納するハッシュテーブルベースのデータ構造です。以下の特徴を持ちます:
- 参照型: マップは参照型であり、実際のデータは別の場所に格納される
- 動的サイズ: 実行時にサイズを変更可能
- 型安全: キーと値の型は宣言時に決定される
- ハッシュベース: 内部的にハッシュテーブルとして実装
Go言語の歴史的コンテキスト
2011年時点のGoは以下の状況でした:
- 開発初期段階: 2009年に発表され、まだ実験的な言語
- 言語仕様の確定作業: Go 1.0リリースに向けた仕様の最終化
- 後方互換性への配慮: 既存コードへの影響を最小限に抑える必要性
- コミュニティの成長: 開発者コミュニティからのフィードバック増加
Russ Coxの役割
Russ Coxは、Go言語の開発において以下の重要な役割を果たしていました:
- 技術リーダー: Go言語の技術的方向性を決定
- コンパイラ開発: gcコンパイラの主要開発者
- 言語設計: 言語仕様の設計と実装
- 標準ライブラリ: 標準ライブラリの設計と実装
技術的詳細
delete関数の実装
新しいdelete
関数は以下の特徴を持ちます:
func delete(m map[Type]Type1, key Type)
- 組み込み関数: 言語レベルでサポートされる組み込み関数
- 戻り値なし: 削除操作は副作用のみを持つ
- 安全な操作: 存在しないキーを削除してもエラーにならない
- 型安全: コンパイル時に型チェックが行われる
従来の構文との比較
従来の構文(廃止予定):
m[key] = 0, false // 第一引数は無視される、第二引数は常にfalse
新しい構文:
delete(m, key) // 明確で直感的
実装箇所の詳細
コミットで変更された主要な箇所:
-
コンパイラ(gc)の変更:
builtin.c.boot
: 組み込み関数の定義追加go.h
: 新しい構文解析のための定義lex.c
: 字句解析でのdelete関数認識typecheck.c
: 型チェック機能の実装walk.c
: 中間表現での処理実装
-
ランタイムの変更:
runtime.go
: ランタイム関数の宣言hashmap.c
: ハッシュマップの削除機能実装
コアとなるコードの変更箇所
1. typecheck.c(37行追加)
この変更により、delete
関数の型チェック機能が追加されました。具体的には:
- 第一引数がマップ型であることの確認
- 第二引数がマップのキー型と一致することの確認
- 戻り値の型チェック(戻り値なし)
2. walk.c(31行追加)
コンパイラの中間表現処理において、delete
関数呼び出しを適切な内部関数呼び出しに変換する処理が追加されました。
3. hashmap.c(22行追加)
ランタイムレベルでのマップ要素削除機能が実装されました。これにより、実際のハッシュテーブルから要素を削除する処理が提供されます。
コアとなるコードの解説
型チェック機能の実装
typecheck.c
での変更により、以下の型チェックが可能になりました:
- 引数の数チェック:
delete
関数は正確に2つの引数を必要とする - マップ型チェック: 第一引数は必ずマップ型でなければならない
- キー型チェック: 第二引数はマップのキー型と互換性がなければならない
中間表現での処理
walk.c
での変更により、以下の変換が行われます:
- 関数呼び出しの認識:
delete(m, key)
をコンパイラが認識 - 内部関数への変換: 適切なランタイム関数呼び出しに変換
- 最適化: 不要な処理の除去とパフォーマンスの最適化
ランタイム実装
hashmap.c
での変更により、以下の機能が提供されます:
- ハッシュ値計算: キーからハッシュ値を計算
- 要素の検索: ハッシュテーブル内での要素の位置特定
- 要素の削除: メモリからの要素除去とテーブル再構築