Goでマップをクリアする方法は?


86

.clear() プリミティブ型のc ++関数のようなものを探していmapます。

または、代わりに新しいマップを作成する必要がありますか?

更新:ご回答ありがとうございます。答えを見て、新しいマップを作成すると、望ましくない不整合が発生する場合があることに気付きました。次の例を考えてみましょう。

var a map[string]string
var b map[string]string

func main() {
    a = make(map[string]string)
    b=a
    a["hello"]="world"
    a = nil
    fmt.Println(b["hello"])
}

.clear()つまり、これは、オブジェクトのコンテンツをクリアするc ++の関数とはまだ異なります。


1
このディスカッションも参照してください:groups.google.com/d/topic/golang-nuts/6yHDC7IYCj4/discussion
perreal 2012

1
組み込みのパージについての議論もあります
perreal 2012

回答:


110

おそらく、新しいマップを作成する必要があります。同じマップが複数のコードによって参照されており、この変更が他のコードに表示されるように1つの部分が値を明示的にクリアする必要がある場合を除いて、既存のマップをわざわざクリアしようとする本当の理由はありません。

そうそう、あなたはおそらくただ言うべきです

mymap = make(map[keytype]valtype)

何らかの理由で既存のマップを本当にクリアする必要がある場合、これは十分に簡単です。

for k := range m {
    delete(m, k)
}

1
では、要素を1つずつ削除することが、それを行う唯一の方法ですか?
lavin 2012

@lavin:うん。これを行うための組み込み関数はなく、任意のマップに対してこれを行うライブラリ関数を使用することはできません。とにかく3行しかない。
リリーバラード

6
すべての値を反復処理しながらマップの内容を変更しても本当に問題ありませんか?他の言語はこれで正しく動作しません。
ジョンジェフリー2012

5
@JohnJeffery:投稿する前にこれをテストしました。動作しているようです。仕様の実際の言語によると、The iteration order over maps is not specified and is not guaranteed to be the same from one iteration to the next. If map entries that have not yet been reached are deleted during iteration, the corresponding iteration values will not be produced. If map entries are inserted during iteration, the behavior is implementation-dependent, but the iteration values for each entry will be produced at most once. If the map is nil, the number of iterations is 0.これはサポートされていることを示しています。
リリーバラード

18
Go 1.11以降、このフォームのマップクリア操作はコンパイラによって最適化されます。github.com/golang/go/blob/master/doc/go1.11.html
ベンジャミンB.

21

C ++とは異なり、Goはガベージコレクションされた言語です。あなたは物事を少し違った考え方をする必要があります。

新しい地図を作るとき

a := map[string]string{"hello": "world"}
a = make(map[string]string)

元のマップは最終的にガベージコレクションされます。手動でクリアする必要はありません。ただし、マップ(およびスライス)は参照型であることを忘れないでください。で作成しますmake()。基になるマップは、参照がない場合にのみガベージコレクションされます。したがって、あなたがするとき

a := map[string]string{"hello": "world"}
b := a
a = make(map[string]string)

元の配列はガベージコレクションされません(bがガベージコレクションされるか、bが他のものを参照するまで)。


3
// Method - I , say book is name of map
for k := range book {
    delete(book, k)
}

// Method - II
book = make(map[string]int)

// Method - III
book = map[string]int{}

-5

これをループで実行しようとしている場合は、初期化を利用してマップをクリアすることができます。例えば:

for i:=0; i<2; i++ {
    animalNames := make(map[string]string)
    switch i {
        case 0:
            animalNames["cat"] = "Patches"
        case 1:
            animalNames["dog"] = "Spot";
    }

    fmt.Println("For map instance", i)
    for key, value := range animalNames {
        fmt.Println(key, value)
    }
    fmt.Println("-----------\n")
}

これを実行すると、前のマップがクリアされ、空のマップから始まります。これは、出力によって確認されます。

$ go run maptests.go 
For map instance 0
cat Patches
-----------

For map instance 1
dog Spot
-----------

3
これは、マップをクリアすることではなく、新しいマップを作成し、ループごとに同じ名前のローカル変数にバインドすることです。
デラニー2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.