удалить карту [ключ] в ходу?

166

У меня есть карта:

var sessions =  map[string] chan int{}

Как мне удалить sessions[key]? Я попытался:

sessions[key] = nil,false;

Это не сработало.


Обновление (ноябрь 2011):

Специальный синтаксис для удаления записей карты удален в версии Go 1 :

Go 1 удалит специальное назначение карты и введет новую встроенную функцию delete: delete(m, x)удалит запись карты, извлеченную выражениемm[x] . ...

jonaz
источник

Ответы:

154

Достаточно странно,

package main

func main () {
    var sessions = map[string] chan int{};
    delete(sessions, "moo");
}

похоже на работу. Это кажется плохим использованием ресурсов, хотя!

Другой способ - проверить существование и использовать само значение:

package main

func main () {
    var sessions = map[string] chan int{};
    sessions["moo"] = make (chan int);
    _, ok := sessions["moo"];
    if ok {
        delete(sessions, "moo");
    }
}
coolaj86
источник
Поиск значения и его повторное использование должны быть дешевле: sessions["moo"] = sessions["moo"], false;(или это неправильно?)
u0b34a0f6ae
Это падает, если ключ не присутствует. Я добавил другое решение, основанное на вашей идее.
1
Безопасно ли это использовать при настройке самой карты?
Хорхе Рамирес
@JorgeRamirez я так не считаю. если вы хотите сделать это, найдите способ перебирать часть ключей вместо самого объекта карты
Seaux
6
Почему второе решение лучше использовать ресурсы? Во втором решении вы делаете два ключевых поиска, тогда как в первом решении вы делаете один ключевой поиск.
thebiggestlebowski
86

Скопировано из примечаний к выпуску Go 1

На старом языке, чтобы удалить запись с ключом kиз карты, представленной m, один написал заявление,

m[k] = value, false

Этот синтаксис был своеобразным частным случаем, единственным присваиванием два к одному. Требуется передать значение (обычно игнорируемое), которое оценивается, но отбрасывается, плюс логическое значение, которое почти всегда было константой false. Это сделало работу, но было странным и предметом спора.

В Go 1 этот синтаксис исчез; вместо этого есть новая встроенная функция delete. Звонок

delete(m, k)

удалит запись карты, извлеченную выражением m[k]. Нет возвращаемого значения. Удаление несуществующей записи не допускается.

Обновление: Запуск go fixбудет преобразовывать выражение вида m[k] = value, falseв , delete(m, k)когда ясно , что игнорировали значение может быть безопасно выброшено из программы и falseотносится к предварительно заданной булевой константе. Инструмент исправления помечает другое использование синтаксиса для проверки программистом.

hannson
источник
55

С Эффективного Go :

Чтобы удалить запись карты, используйте встроенную функцию удаления, аргументами которой являются карта и ключ для удаления. Это безопасно, даже если ключ уже отсутствует на карте.

delete(timeZone, "PDT")  // Now on Standard Time
Дьёрдь Андрасек
источник
sessions.go:6: cannot use 0 (type int) as type chan int
3
@Kinopiko: Я не думаю, что Jurily хотел, чтобы OP использовал этот фрагмент кода. Он просто скопировал пример из документации.
Исаия
2
Похоже, что это было удалено с тех пор, какassignment count mismatch: 1 = 2 (use delete)
ghayes
0

Используйте make (chan int)вместо nil. Первое значение должно быть того же типа, что и ваша карта.

package main

import "fmt"

func main() {

    var sessions = map[string] chan int{}
    sessions["somekey"] = make(chan int)

    fmt.Printf ("%d\n", len(sessions)) // 1

    // Remove somekey's value from sessions
    delete(sessions, "somekey")

    fmt.Printf ("%d\n", len(sessions)) // 0
}

ОБНОВЛЕНИЕ: исправил мой ответ.

Исайя
источник
sessions.go:6: cannot use 0 (type int) as type chan int
Ой, забыл, что я тоже это убрал: P
Исаия
package main func main () {var sessions = map[string] chan int{};sessions["moo"] = make (chan int);}
Вышеуказанное компилируется и запускается на моей версии Go.