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

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

このコミットは、Go言語の公式ドキュメントであるeffective_goにおいて、マップからの要素削除に関する記述を、古い構文から新しいdelete組み込み関数を使用する構文に更新するものです。これは、Go 1.0のリリースに伴う言語仕様の変更を反映しています。

コミット

commit 14efdea35986e47db79c8b1e8d5e57dc13e8727a
Author: Rob Pike <r@golang.org>
Date:   Sun Feb 12 09:11:44 2012 +1100

    effective_go: use new map deletion syntax
    
    Fixes #2984.
    
    R=golang-dev, gri
    CC=golang-dev
    https://golang.org/cl/5652071

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

https://github.com/golang/go/commit/14efdea35986e47db79c8b1e8d5e57dc13e8727a

元コミット内容

このコミットは、effective_goドキュメント内でマップからの要素削除に関する記述を修正し、新しいマップ削除構文を使用するように変更します。具体的には、以前のmap[key] = value, falseという形式から、delete(map, key)という新しい組み込み関数を使用する形式へと更新しています。この変更は、Issue #2984を修正するものです。

変更の背景

Go言語は、2012年3月にGo 1.0として安定版がリリースされるまで、活発な開発と仕様変更が行われていました。その過程で、マップからの要素削除の構文も変更されました。

Go 1.0以前は、マップからエントリを削除するために、map[key] = value, falseという特殊な多値代入構文が使用されていました。この構文は、マップに値を設定する通常の多値代入(例: map[key] = value, true)と似ていますが、第2のブール値がfalseである場合に削除を意味するという、やや直感的ではない振る舞いでした。特に、valueの部分は削除操作においては意味を持たず、慣用的ではありませんでした。

Go開発チームは、この構文がGo言語の設計哲学である「シンプルさ」や「明瞭さ」に反すると判断し、より明確で専用の組み込み関数を導入することを決定しました。その結果、delete関数が導入され、マップからの要素削除がより意図的に、かつ簡潔に表現できるようになりました。

このコミットは、Go言語の重要な公式ドキュメントの一つであるeffective_goが、この新しい言語仕様に準拠するように更新されたことを示しています。ドキュメントの正確性を保ち、開発者が最新かつ推奨されるプラクティスを学べるようにするための重要な更新でした。

前提知識の解説

Go言語のマップ (Map)

Go言語におけるマップは、キーと値のペアを格納するための組み込みデータ構造です。他の言語では「ハッシュマップ」「連想配列」「辞書」などと呼ばれるものに相当します。

  • 宣言と初期化: make(map[KeyType]ValueType)で作成します。例: m := make(map[string]int)
  • 要素の追加/更新: m[key] = valueのように代入します。キーが既に存在すれば値が更新され、存在しなければ新しいエントリが追加されます。
  • 要素の取得: value := m[key]のように取得します。キーが存在しない場合、値の型のゼロ値が返されます。
  • 存在チェック: value, ok := m[key]のように多値代入で取得すると、okというブール値でキーが存在したかどうかを確認できます。oktrueならキーが存在し、falseなら存在しませんでした。

effective_goドキュメント

effective_goは、Go言語の公式ドキュメントの一つで、Go言語を効果的かつ慣用的に記述するためのヒントやガイドラインを提供しています。Go言語の設計思想、基本的な構文、データ構造、並行処理など、幅広いトピックをカバーしており、Goプログラマーにとって非常に重要なリソースです。このドキュメントは、Go言語の進化に合わせて定期的に更新されます。

技術的詳細

このコミットの核心は、Go言語のマップからの要素削除構文の変更です。

旧構文 (Go 1.0以前)

Go 1.0以前では、マップmからキーkに対応するエントリを削除するには、以下のような構文が用いられました。

timeZone["PDT"] = 0, false // Now on Standard Time

この構文は、マップへの多値代入の特殊なケースとして扱われました。通常、map[key] = value, okのような多値代入は、oktrueの場合にvaluekeyに関連付け、falseの場合にkeyを削除するという意味合いを持っていました。しかし、この「削除」の意図を伝えるために、意味のないvalue(この例では0)を渡す必要があり、コードの意図が不明瞭になるという問題がありました。

新構文 (Go 1.0以降)

Go 1.0のリリースに伴い、マップからの要素削除専用の組み込み関数deleteが導入されました。

delete(timeZone, "PDT") // Now on Standard Time

delete関数は、2つの引数を取ります。

  1. 第一引数: 削除対象のマップ
  2. 第二引数: 削除したいエントリのキー

この関数は値を返しません。

delete関数の振る舞い

  • キーが存在する場合: 指定されたキーとそれに対応する値がマップから削除されます。
  • キーが存在しない場合: 何も起こりません(no-op)。エラーは発生せず、パニックも起こりません。これは、削除操作が冪等であることを意味し、コードの堅牢性を高めます。
  • nilマップに対する操作: delete関数をnilマップに対して呼び出しても、Go 1.0の初期段階ではパニックが発生する可能性がありましたが、その後のバージョン(2012年12月頃)でnilマップに対するdeleteはno-opとなるように変更されました。これにより、nilマップのチェックを明示的に行う必要がなくなり、コードが簡潔になります。

go fixツール

Go言語には、古いAPIや構文から新しいものへコードを自動的に変換するgo fixというツールが提供されています。マップ削除構文の変更もgo fixの対象となり、開発者は既存のコードベースを容易に新しいdelete構文に移行することができました。

このコミットは、effective_goドキュメント内の説明とコード例を、この新しいdelete関数を使用するように更新することで、Go言語の最新かつ推奨されるプラクティスを反映させています。

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

このコミットでは、doc/effective_go.htmldoc/effective_go.tmplの2つのファイルが変更されています。これらのファイルは、effective_goドキュメントのHTML版とテンプレート版です。

diff --git a/doc/effective_go.html b/doc/effective_go.html
index edaffd733d..e3e19bd392 100644
--- a/doc/effective_go.html
+++ b/doc/effective_go.html
@@ -1418,13 +1418,13 @@ identifier in place of the usual variable for the value.
 _, present := timeZone[tz]
 </pre>
 <p>
-To delete a map entry, turn the multiple assignment around by placing
-an extra boolean on the right; if the boolean is false, the entry
-is deleted. It's safe to do this even if the key is already absent
+To delete a map entry, use the <code>delete</code>
+built-in function, whose arguments are the map and the key to be deleted.
+It's safe to do this this even if the key is already absent
 from the map.
 </p>
 <pre>
-timeZone["PDT"] = 0, false  // Now on Standard Time
+delete(timeZone, "PDT")  // Now on Standard Time
 </pre>
 
 <h3 id=\"printing\">Printing</h3>
diff --git a/doc/effective_go.tmpl b/doc/effective_go.tmpl
index 8875495073..5763cacdab 100644
--- a/doc/effective_go.tmpl
+++ b/doc/effective_go.tmpl
@@ -1414,13 +1414,13 @@ identifier in place of the usual variable for the value.
 _, present := timeZone[tz]
 </pre>
 <p>
-To delete a map entry, turn the multiple assignment around by placing
-an extra boolean on the right; if the boolean is false, the entry
-is deleted. It's safe to do this even if the key is already absent
+To delete a map entry, use the <code>delete</code>
+built-in function, whose arguments are the map and the key to be deleted.
+It's safe to do this this even if the key is already absent
 from the map.
 </p>
 <pre>
-timeZone["PDT"] = 0, false  // Now on Standard Time
+delete(timeZone, "PDT")  // Now on Standard Time
 </pre>
 
 <h3 id=\"printing\">Printing</h3>

コアとなるコードの解説

変更は、effective_goドキュメントの「Maps」セクションにおけるマップからの要素削除に関する説明とコード例に集中しています。

  1. 説明文の変更:

    • 旧: "To delete a map entry, turn the multiple assignment around by placing an extra boolean on the right; if the boolean is false, the entry is deleted."
    • 新: "To delete a map entry, use the delete built-in function, whose arguments are the map and the key to be deleted." この変更により、マップからの要素削除が多値代入の特殊なケースではなく、専用のdelete組み込み関数を使用する明確な操作として説明されるようになりました。delete関数がマップとキーを引数として取ることも明記されています。
  2. コード例の変更:

    • 旧: timeZone["PDT"] = 0, false // Now on Standard Time
    • 新: delete(timeZone, "PDT") // Now on Standard Time 実際のコード例も、古い多値代入構文から新しいdelete関数を使用した構文に置き換えられています。これにより、読者は推奨される最新の削除方法を直接コードで確認できるようになります。

これらの変更は、Go言語のマップ削除構文の進化を正確に反映し、ドキュメントが常に最新の言語仕様とベストプラクティスを提供することを保証しています。

関連リンク

参考にした情報源リンク