Go'da bir harita nasıl temizlenir?


86

.clear() İlkel tür için c ++ işlevi gibi bir şey arıyorum map.

Yoksa bunun yerine yeni bir harita mı oluşturmalıyım?

Güncelleme: Cevaplarınız için teşekkür ederiz. Cevaplara bakarak, bazen yeni bir harita oluşturmanın, istemediğimiz bazı tutarsızlıklara yol açabileceğini fark ettim. Aşağıdaki örneği düşünün:

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"])
}

Demek istediğim, bu hala .clear()c ++ 'daki işlevden farklıdır, bu da nesnedeki içeriği temizler.



1
dahili temizleme hakkında da tartışma var
perreal

Yanıtlar:


110

Muhtemelen yeni bir harita oluşturmalısınız. Aynı haritaya birden fazla kod parçası tarafından atıfta bulunulmadıkça ve bir parçanın bu değişikliğin diğer kod parçaları tarafından görülebilmesi için değerleri açıkça temizlemesi gerekmedikçe, mevcut olanı temizlemeye çalışmak için hiçbir gerçek neden yoktur.

Yani evet, muhtemelen söylemelisin

mymap = make(map[keytype]valtype)

Herhangi bir nedenle mevcut haritayı gerçekten temizlemeniz gerekiyorsa, bu yeterince basittir:

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

1
Öyleyse, öğeleri tek tek silmek bunu yapmanın tek yolu mu?
lavin

@lavin: Evet. Bunu yapacak yerleşik bir işlev yoktur ve bunu rastgele haritalar için yapan bir kitaplık işlevine sahip olamazsınız. Ama yine de sadece 3 satır.
Lily Ballard

6
Tüm değerleri yinelerken bir haritanın içeriğini değiştirmek gerçekten uygun mudur? Diğer diller bununla doğru çalışmayacaktır.
John Jeffery

5
@JohnJeffery: Bunu göndermeden önce test ettim. Çalışıyor gibi görünüyor. Spesifikasyondaki gerçek dil, 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.Bu, desteklendiğini gösteriyor.
Lily Ballard

18
Go 1.11'den başlayarak, bu formun harita temizleme işlemleri derleyici tarafından optimize edilmektedir. github.com/golang/go/blob/master/doc/go1.11.html
Benjamin B.

21

C ++ 'dan farklı olarak Go, çöp toplanan bir dildir. İşleri biraz farklı düşünmeniz gerekiyor.

Yeni bir harita yaptığınızda

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

orijinal harita eninde sonunda çöp olarak toplanacaktır; elle temizlemenize gerek yoktur. Ancak haritaların (ve dilimlerin) referans türleri olduğunu unutmayın; onları ile yaratırsınız make(). Altta yatan harita, yalnızca kendisine referans olmadığında çöp olarak toplanacaktır. Böylece, yaptığınızda

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

orijinal dizi çöp olarak toplanmayacaktır (b çöpte toplanana veya b başka bir şeye başvurana kadar).


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

Bunu bir döngü içinde yapmaya çalışıyorsanız, haritayı sizin için temizlemek için başlatma işleminden yararlanabilirsiniz. Örneğin:

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")
}

Bunu çalıştırdığınızda, önceki haritayı temizler ve boş bir haritayla başlar. Bu, çıktıyla doğrulanır:

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

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

3
Bu haritayı temizlemek değil, yeni bir harita yapmak ve her döngüde aynı ada sahip yerel bir değişkene bağlanmaktır.
Delaney
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.