Jak wyczyścić mapę w Go?

85

Szukam czegoś takiego jak funkcja C ++ .clear() dla typu pierwotnego map.

A może zamiast tego powinienem po prostu utworzyć nową mapę?

Aktualizacja: Dziękuję za odpowiedzi. Patrząc na odpowiedzi, właśnie zdałem sobie sprawę, że czasami tworzenie nowej mapy może prowadzić do niespójności, której nie chcemy. Rozważmy następujący przykład:

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

Chodzi mi o to, że nadal różni się to od .clear()funkcji w c ++, która wyczyści zawartość obiektu.

lavin
źródło
1
zobacz także tę dyskusję: groups.google.com/d/topic/golang-nuts/6yHDC7IYCj4/discussion
perreal
1
jest też dyskusja na temat wbudowanego oczyszczania
perreal,

Odpowiedzi:

108

Powinieneś prawdopodobnie po prostu utworzyć nową mapę. Nie ma prawdziwego powodu, aby zawracać sobie głowę próbą wyczyszczenia istniejącej, chyba że do tej samej mapy odwołuje się wiele fragmentów kodu, a jeden element wyraźnie musi wyczyścić wartości, tak aby ta zmiana była widoczna dla innych fragmentów kodu.

Więc tak, prawdopodobnie powinieneś po prostu powiedzieć

mymap = make(map[keytype]valtype)

Jeśli naprawdę potrzebujesz wyczyścić istniejącą mapę z jakiegokolwiek powodu, jest to dość proste:

for k := range m {
    delete(m, k)
}
Lily Ballard
źródło
1
Czyli usuwanie elementów jeden po drugim to jedyny sposób, aby to zrobić?
lavin
@lavin: Tak. Nie ma wbudowanej funkcji, która mogłaby to zrobić, i nie można mieć funkcji bibliotecznej, która robi to dla dowolnych map. Ale i tak to tylko 3 linie.
Lily Ballard,
6
Czy naprawdę można modyfikować zawartość mapy podczas iteracji po wszystkich wartościach? Inne języki nie będą z tym działać poprawnie.
John Jeffery,
5
@JohnJeffery: Przetestowałem to przed opublikowaniem. Wydaje się działać. Rzeczywisty język ze specyfikacji mówi, że 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.to sugeruje, że jest obsługiwany.
Lily Ballard
18
Począwszy od wersji Go 1.11, operacje czyszczenia mapy w tym formularzu są optymalizowane przez kompilator. github.com/golang/go/blob/master/doc/go1.11.html
Benjamin B.
20

W przeciwieństwie do C ++, Go jest językiem zbierania elementów bezużytecznych. Musisz myśleć trochę inaczej.

Kiedy tworzysz nową mapę

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

oryginalna mapa zostanie ostatecznie zebrana jako śmieci; nie musisz czyścić go ręcznie. Pamiętaj jednak, że mapy (i wycinki) są typami referencyjnymi; tworzysz je za pomocą make(). Mapa bazowa będzie zbierana jako śmieci tylko wtedy, gdy nie ma do niej odwołań. Tak więc, kiedy to robisz

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

oryginalna tablica nie zostanie usunięta (dopóki b nie zostanie zebrana lub b nie będzie oznaczać czegoś innego).

John Smith
źródło
2
// 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{}
Sumer
źródło
-5

Jeśli próbujesz to zrobić w pętli, możesz skorzystać z inicjalizacji, aby wyczyścić mapę. Na przykład:

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

Kiedy to wykonasz, usuwa poprzednią mapę i zaczyna od pustej mapy. Potwierdza to wynik:

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

For map instance 1
dog Spot
-----------
leemic
źródło
3
To nie jest czyszczenie mapy, ale tworzenie nowej mapy i powiązanie ze zmienną lokalną o tej samej nazwie w każdej pętli.
Delaney