Як очистити карту в Go?


85

Я шукаю щось на зразок функції c ++ .clear() для примітивного типу 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
перреаль

1
є також дискусія щодо вбудованої продувки
перреаль

Відповіді:


108

Ймовірно, вам слід просто створити нову карту. Немає жодної реальної причини турбуватися про спроби очистити існуючу, якщо на одну і ту ж карту не посилаються кілька фрагментів коду, а одна частина чітко вимагає очищення значень, щоб ця зміна була видимою для інших частин коду.

Так так, напевно, слід просто сказати

mymap = make(map[keytype]valtype)

Якщо вам дійсно потрібно очистити існуючу карту з будь-якої причини, це досить просто:

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

1
Тож видалення елементів по одному - це єдиний спосіб це зробити?
lavin

@lavin: Так. Для цього немає вбудованої функції, і ви не можете мати бібліотечну функцію, яка робить це для довільних карт. Але це все-таки лише 3 рядки.
Лілі Баллард

6
Чи справді нормально змінювати вміст карти, перебираючи всі значення? Інші мови з цим працюватимуть некоректно.
Джон Джеффрі,

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
Бенджамін Б.

20

На відміну від 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 не стосується чогось іншого).


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{}

-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
Це не очищення карти, а створення нової карти та прив’язка до локальної змінної з однаковим ім’ям кожен цикл.
Delaney
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.