Go言語入門:言語仕様 -Vol.129-

スポンサーリンク
Go言語入門:言語仕様 -Vol.129- 用語解説
Go言語入門:言語仕様 -Vol.129-
この記事は約4分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

本日は、Go言語の言語仕様について解説しています。

スポンサーリンク

背景

Go言語を学び始めて、公式の「The Go Programming Language Specification(言語仕様書)」を開いてみたものの、「英語で書かれていて読むのが大変…」「専門用語ばかりで何を言っているのかわからない…」と感じたことはありませんか? 実は、多くのGo初心者が同じ壁にぶつかっています。

言語仕様書は、Go言語の「正式な取扱説明書」のような存在です。プログラミング言語がどのように動くのか、どんなルールで書くべきなのかが詳しく書かれていますが、その分、初めて読む人には難しく感じられるのも事実です。

そこでこの記事では、言語仕様書の導入部分を丁寧な日本語訳とともに、初心者の方でも理解しやすい補足説明を加えてお届けします。「強く型付けされている」「ガベージコレクション」「並行プログラミング」といった専門用語も、具体例を交えながらわかりやすく解説していきます。

言語仕様書は難しそうに見えますが、一つひとつの概念を丁寧に読み解いていけば、必ず理解できます。一緒に、Go言語の基礎をしっかり学んでいきましょう!

mapの要素の削除(Deletion of map elements)

組み込み関数 delete は、map m からキー k を持つ要素を削除する。値 km のキー型に代入可能でなければならない。

delete(m, k)  // map m から要素 m[k] を削除する

m の型が型パラメータの場合、その型集合のすべての型はmapでなければならず、すべて同一のキー型を持たなければならない。

map mnil であるか、要素 m[k] が存在しない場合、delete は何もしない。


解説

delete の基本

delete は、mapから指定したキーの要素を削除する組み込み関数です。

m := map[string]int{"a": 1, "b": 2, "c": 3}
delete(m, "b")
fmt.Println(m)  // map[a:1 c:3]

存在しないキーを削除してもパニックしない

存在しないキーを指定しても、何も起きません。エラーにもパニックにもなりません。

m := map[string]int{"a": 1}
delete(m, "zzz")  // 何も起きない
fmt.Println(m)     // map[a:1]

事前に「キーが存在するか」をチェックする必要がないので、安全に使えます。

nil map に対しても安全

nil の map に対して delete を呼んでも、パニックしません。

var m map[string]int  // nil
delete(m, "a")        // 何も起きない

ただし、nil の map への代入はパニックすることを覚えておきましょう。delete が安全なのは「削除するものがそもそも存在しない」のと同じ扱いだからです。

var m map[string]int  // nil
delete(m, "a")        // OK(何もしない)
m["a"] = 1            // パニック!(nil map への代入)

delete は値を返さない

delete は戻り値がありません。削除が成功したかどうかを直接知ることはできません。必要な場合は、事前にキーの存在を確認します。

m := map[string]int{"a": 1, "b": 2}

// 削除前にキーの存在を確認したい場合
if _, ok := m["b"]; ok {
    delete(m, "b")
    fmt.Println("削除しました")
} else {
    fmt.Println("キーが存在しません")
}

clear との使い分け

Go 1.21 で追加された clear との違いを整理しておきましょう。

m := map[string]int{"a": 1, "b": 2, "c": 3}

delete(m, "a")   // 1つの要素だけ削除
clear(m)          // すべての要素を削除
deleteclear
対象指定した1つのキーすべてのキー
導入バージョンGo 1.0Go 1.21

ループ内での削除

range ループ中にmapの要素を削除しても安全です。Go の仕様で許可されています。

m := map[string]int{"a": 1, "b": 2, "c": 3, "d": 4}
for k, v := range m {
    if v%2 == 0 {
        delete(m, k)  // ループ中の削除は安全
    }
}
fmt.Println(m)  // map[a:1 c:3]

ただし、ループ中に追加したエントリが同じループで処理されるかどうかは不定です(mapの反復順序は保証されないため)。

おわりに 

本日は、Go言語の言語仕様について解説しました。

よっしー
よっしー

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました