[インデックス 14653] ファイルの概要
このコミットは、Go言語の組み込み関数 delete()
のコメントを修正し、nil
マップに対する delete()
の挙動がパニックではなくno-op(何もしない)になったことを反映しています。
コミット
commit 0b50a5dad78193fecae52f18a01df928c229eb32
Author: Jingcheng Zhang <diogin@gmail.com>
Date: Fri Dec 14 09:13:42 2012 -0800
builtin: correct comment on builtin function delete().
Delete on a nil map is now a no-op.
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/6938054
---
src/pkg/builtin/builtin.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/pkg/builtin/builtin.go b/src/pkg/builtin/builtin.go
index a30943b894..91d263a623 100644
--- a/src/pkg/builtin/builtin.go
+++ b/src/pkg/builtin/builtin.go
@@ -124,8 +124,8 @@ func append(slice []Type, elems ...Type) []Type
func copy(dst, src []Type) int
// The delete built-in function deletes the element with the specified key
-// (m[key]) from the map. If there is no such element, delete is a no-op.\n-// If m is nil, delete panics.
+// (m[key]) from the map. If m is nil or there is no such element, delete\n+// is a no-op.
func delete(m map[Type]Type1, key Type)
// The len built-in function returns the length of v, according to its type:\n
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/0b50a5dad78193fecae52f18a01df928c229eb32
元コミット内容
builtin: correct comment on builtin function delete().
Delete on a nil map is now a no-op.
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/6938054
変更の背景
このコミットの背景には、Go言語のマップ型における delete
組み込み関数の挙動の変更があります。以前のGoのバージョンでは、nil
マップに対して delete
関数を呼び出すとパニック(ランタイムエラー)が発生していました。しかし、Go言語の設計思想として、一般的な操作においては nil
値に対する操作が安全であるべきという考え方があります。例えば、nil
スライスへの append
や nil
チャネルからの読み取りなどはパニックを起こしません。
マップの場合、nil
マップからの読み取りはゼロ値を返し、パニックは発生しません。この一貫性を保つため、nil
マップに対する delete
操作もパニックではなく、何もしない(no-op)という挙動に変更されました。この変更により、開発者は delete
を呼び出す前にマップが nil
かどうかを明示的にチェックする必要がなくなり、コードの記述がより簡潔かつ堅牢になります。
このコミット自体は、実際の delete
関数の実装を変更するものではなく、その挙動変更に伴って、src/pkg/builtin/builtin.go
内の delete
関数のコメントを、新しい挙動に合わせて更新することが目的です。これは、Go言語のドキュメントと実際の挙動との間に齟齬がないようにするための重要な修正です。
前提知識の解説
Go言語のマップ (map)
Go言語のマップは、キーと値のペアを格納するハッシュテーブルの実装です。キーは一意であり、値にマッピングされます。マップは make
関数で初期化するか、マップリテラルを使用して作成します。
// マップの宣言と初期化
var m map[string]int // nilマップ
m = make(map[string]int) // 空のマップ
m2 := map[string]int{"apple": 1, "banana": 2} // マップリテラル
nil
マップ
Goにおいて、マップ型の変数を宣言しただけで初期化しない場合、その変数は nil
マップとなります。nil
マップは、内部的にデータ構造が割り当てられていない状態を指します。
nil
マップへの書き込み:nil
マップに要素を追加しようとすると、ランタイムパニックが発生します。これは、データ構造が存在しないため、要素を格納する場所がないためです。nil
マップからの読み取り:nil
マップから要素を読み取ろうとすると、パニックは発生せず、その値型のゼロ値が返されます。例えば、map[string]int
の場合、int
のゼロ値である0
が返されます。nil
マップの長さ:len(nilMap)
は0
を返します。
delete
組み込み関数
delete
はGo言語に組み込まれている関数で、マップから指定されたキーの要素を削除するために使用されます。
func delete(m map[Type]Type1, key Type)
m
: 要素を削除する対象のマップ。key
: 削除する要素のキー。
delete
関数は、指定されたキーがマップに存在しない場合でもパニックを起こしません。その場合、単に何もしません(no-op)。
no-op (No Operation)
no-opとは、「何もしない操作」を意味します。プログラミングにおいては、特定の条件が満たされた場合や、エラーではないが処理を行う必要がない場合に、プログラムが何もせず、しかしエラーも発生させずに続行する挙動を指します。この文脈では、nil
マップに対して delete
を呼び出しても、プログラムがクラッシュすることなく、単に要素の削除処理が行われないことを意味します。
技術的詳細
このコミットの技術的な詳細の中心は、Go言語の delete
組み込み関数が nil
マップに対してどのように振る舞うかという仕様変更と、それに対応するドキュメントの更新です。
変更前の挙動とコメント
変更前は、delete
関数が nil
マップに対して呼び出されるとパニックが発生するという仕様でした。これに伴い、src/pkg/builtin/builtin.go
内の delete
関数のコメントは以下のようになっていました。
// The delete built-in function deletes the element with the specified key
// (m[key]) from the map. If there is no such element, delete is a no-op.
// If m is nil, delete panics.
このコメントの最後の行「If m is nil, delete panics.」が、nil
マップに対する delete
がパニックを引き起こすことを明示していました。
変更後の挙動とコメント
Go言語の進化の過程で、nil
マップに対する delete
の挙動が変更され、パニックではなくno-opとなるように仕様が改定されました。この変更は、Goの設計原則である「ゼロ値の有用性」や「安全なデフォルト」に沿ったものです。nil
マップからの読み取りがパニックを起こさないのと同様に、nil
マップからの削除も安全に行えるようになりました。
この仕様変更を受けて、コメントも以下のように更新されました。
// The delete built-in function deletes the element with the specified key
// (m[key]) from the map. If m is nil or there is no such element, delete
// is a no-op.
変更点としては、「If m is nil, delete panics.」が削除され、「If m is nil or there is no such element, delete is a no-op.」という記述に置き換えられました。これにより、nil
マップの場合でも、キーが存在しない場合と同様に delete
がno-opとして振る舞うことが明確に示されています。
影響と利点
この変更は、Go言語のコードの堅牢性と簡潔性を向上させます。
- 堅牢性: 開発者は
delete
を呼び出す前にマップがnil
かどうかを明示的にチェックする必要がなくなります。これにより、nil
マップに対するdelete
呼び出しが原因で予期せぬパニックが発生するリスクが減少します。 - 簡潔性:
if m != nil { delete(m, key) }
のような冗長なチェックが不要になり、コードがよりシンプルになります。
この変更は、Go言語の標準ライブラリやアプリケーションコード全体にわたって、より安全で予測可能なマップ操作を可能にするための重要な一歩でした。
コアとなるコードの変更箇所
変更は src/pkg/builtin/builtin.go
ファイルの delete
関数のコメント部分にあります。
--- a/src/pkg/builtin/builtin.go
+++ b/src/pkg/builtin/builtin.go
@@ -124,8 +124,8 @@ func append(slice []Type, elems ...Type) []Type
func copy(dst, src []Type) int
// The delete built-in function deletes the element with the specified key
-// (m[key]) from the map. If there is no such element, delete is a no-op.\n-// If m is nil, delete panics.
+// (m[key]) from the map. If m is nil or there is no such element, delete\n+// is a no-op.
func delete(m map[Type]Type1, key Type)
// The len built-in function returns the length of v, according to its type:\n
具体的には、以下の2行が変更されています。
- 削除された行:
// If m is nil, delete panics.
- 追加された行:
// is a no-op.
(前の行と合わせてIf m is nil or there is no such element, delete is a no-op.
となる)
コアとなるコードの解説
このコミットにおけるコアとなるコードの変更は、Go言語の組み込み関数 delete
のドキュメンテーションコメントの修正です。実際の delete
関数のロジック自体は変更されていません。この変更は、Go言語のマップに対する delete
関数の挙動が、nil
マップの場合にパニックを起こすのではなく、何もしない(no-op)ように変更されたという、言語仕様の変更を反映するためのものです。
src/pkg/builtin/builtin.go
ファイルは、Go言語の組み込み関数(append
, copy
, delete
, len
など)の宣言と、それらの関数のドキュメンテーションコメントを定義しているファイルです。これらのコメントは、Goの公式ドキュメントや go doc
コマンドで表示される情報源となります。
変更前は、delete
関数のコメントには「If m is nil, delete panics.
(もし m
が nil
なら、delete
はパニックを起こす)」と記述されていました。これは、当時の delete
関数の実際の挙動を正確に反映していました。
しかし、Go言語の進化に伴い、nil
マップに対する delete
の挙動が変更され、パニックではなくno-opとなるように仕様が改定されました。この変更は、Goの設計原則である「ゼロ値の有用性」に沿ったもので、nil
マップからの読み取りがパニックを起こさないのと同様に、nil
マップからの削除も安全に行えるようにするためです。
このコミットでは、この言語仕様の変更に合わせて、コメントの記述を「If m is nil or there is no such element, delete is a no-op.
(もし m
が nil
であるか、そのような要素が存在しない場合、delete
はno-opである)」に修正しています。これにより、Goのドキュメントが常に最新の言語仕様と一致するように保たれ、開発者が誤解するのを防ぎます。
この修正は、Go言語の安定性と信頼性を維持するために、ドキュメンテーションが実際の挙動と同期していることの重要性を示しています。
関連リンク
- Go言語のマップに関する公式ドキュメント: https://go.dev/blog/maps
- Go言語の仕様 - マップ型: https://go.dev/ref/spec#Map_types
- Go言語の仕様 - 組み込み関数
delete
: https://go.dev/ref/spec#Delete - このコミットのGo CL (Change List): https://golang.org/cl/6938054
参考にした情報源リンク
- Web検索結果: "Go delete nil map no-op behavior change"
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEc00ntAUeS0I3yfTXTyxpTRvbg1ZD5qhH4b2-_zMib0XKCzlhXGIi7_mDH1CtkZI3SWUt_qRtYL4oidlW6SZk52ENXqr197uR7luQvN0CqiH7CdLdya3yixOC5q3XHNCRwVT45OpTrin7R1N66Q_2MPRDPnNLFCe7Jl9Qed8kz5Ridk3NMfcjjsg==
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHHin13r0dua95GAquWVFUK6JaJ7HPHeR76srxQghn8BSo9uDMNRNxDSWXeltaoHeF5aMi1bUICzM6X6j1Q_CgfNcOJO913Ws8WpdG2pOFODZsJXME1E1EnMM-vY-U27CIPjttJd-QsPf9RG5FT-1H5ZzJKjtX0nt0ECe8k9c-WTb1fWKzJVSoZv82eLHISLYgH6Y8yBsbqZB4=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQH91fO49nlEhJlXq33w9lVYueWL6RYS27CjMU2Bh2CPBL7EoqvWGSiToxFmPEtuz4eWGayTuplUlcwPxpNqoYk4uznXuPTxcaQwHtC3spoY9NLDq5378ADeGyw-LwvGX2H-jKvV8_8fF3PkgkWh1Q08MXdn5ASN3Ic8yD5TakSs7QsPokPkrJvQiaYAXB4lZpFTgN8j_vVM6P2RVCF39yQ=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGKCvqO5O1E_I-RFGDe795Y8Z_Np1DX_eKnbovKlNHQfUlTtCcWOUfrnKiqYMGa5xiOQp44Jh3vAC9wHRQ-F-cLJZYu4rRP2xPdzY9mo6LKuFAW_lTU5244nLQ_arcQVyKqKEzRVcnCKIiEBSExyItBx0cUIHsa8rI-VI3whg==