¿Cómo borrar un mapa en Go?

85

Estoy buscando algo como la función c ++ .clear() para el tipo primitivo map.

¿O debería crear un mapa nuevo en su lugar?

Actualización: Gracias por sus respuestas. Al mirar las respuestas, me di cuenta de que, a veces, la creación de un mapa nuevo puede generar algunas inconsistencias que no queremos. Considere el siguiente ejemplo:

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

Quiero decir, esto sigue siendo diferente de la .clear()función en c ++, que borrará el contenido del objeto.

lavin
fuente
1
también vea esta discusión: groups.google.com/d/topic/golang-nuts/6yHDC7IYCj4/discussion
perreal
1
también hay una discusión sobre la purga incorporada
perreal

Respuestas:

108

Probablemente debería crear un nuevo mapa. No hay ninguna razón real para molestarse en intentar borrar uno existente, a menos que el mismo mapa esté siendo referido por varios fragmentos de código y un fragmento necesite explícitamente borrar los valores de manera que este cambio sea visible para los otros fragmentos de código.

Así que sí, probablemente deberías decir

mymap = make(map[keytype]valtype)

Si realmente necesita borrar el mapa existente por cualquier motivo, esto es bastante simple:

for k := range m {
    delete(m, k)
}
Lily Ballard
fuente
1
Entonces, ¿eliminar elementos uno por uno es la única forma de hacerlo?
lavin
@lavin: Sí. No hay una función incorporada para hacer esto, y no puede tener una función de biblioteca que haga esto para mapas arbitrarios. Pero son solo 3 líneas de todos modos.
Lily Ballard
6
¿Está realmente bien modificar el contenido de un mapa mientras se itera por todos los valores? Otros idiomas no funcionarán correctamente con esto.
John Jeffery
5
@JohnJeffery: Probé esto antes de publicarlo. Parece funcionar. El lenguaje real de la especificación dice 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.Esto sugiere que es compatible.
Lily Ballard
18
A partir de Go 1.11, el compilador optimiza las operaciones de borrado de mapas de este formulario. github.com/golang/go/blob/master/doc/go1.11.html
Benjamin B.
20

A diferencia de C ++, Go es un lenguaje de recolección de basura. Necesitas pensar las cosas de manera un poco diferente.

Cuando haces un mapa nuevo

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

el mapa original se recogerá eventualmente como basura; no es necesario borrarlo manualmente. Pero recuerde que los mapas (y los cortes) son tipos de referencia; los crea con make(). El mapa subyacente se recolectará como basura solo cuando no haya referencias a él. Por tanto, cuando lo hagas

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

la matriz original no será recolectada como basura (hasta que b sea recolectada o b se refiera a otra cosa).

John Smith
fuente
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
fuente
-5

Si está intentando hacer esto en un bucle, puede aprovechar la inicialización para borrar el mapa por usted. Por ejemplo:

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

Cuando ejecuta esto, borra el mapa anterior y comienza con un mapa vacío. Esto es verificado por la salida:

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

For map instance 1
dog Spot
-----------
leemic
fuente
3
Eso no es borrar el mapa, sino hacer un nuevo mapa y vincularlo a una variable local con el mismo nombre en cada ciclo.
Delaney