325

I have a map:

var sessions =  map[string] chan int{}

How do I delete sessions[key]? I tried:

sessions[key] = nil,false;

That didn't work.

Update (November 2011):

The special syntax for deleting map entries is removed in Go version 1:

Go 1 will remove the special map assignment and introduce a new built-in function, delete: delete(m, x) will delete the map entry retrieved by the expression m[x]. ...

jonaz
  • 3,764
  • 2
  • 20
  • 20

5 Answers5

334

Go introduced a delete(map, key) function:

package main

func main () {
    var sessions = map[string] chan int{};
    delete(sessions, "moo");
}
  • Looking up the value and reusing it must be cheaper: `sessions["moo"] = sessions["moo"], false;` (or is that wrong?) – u0b34a0f6ae Nov 15 '09 at 22:22
  • That crashes unless the key is present. I've added another solution based on your idea. –  Nov 18 '09 at 06:22
  • 1
    Is this safe to use while for-ranging the map itself? – Jorge Ramirez Sep 11 '18 at 18:38
  • 1
    @JorgeRamirez i don't believe so. if you want to do that find a way to iterate over a slice of the keys instead of the map object itself – Seaux Feb 12 '19 at 17:43
  • 24
    Why is the second solution a better use of resources? In the second solution you do two key lookups, whereas in the first solution, you one key lookup. – thebiggestlebowski Mar 05 '19 at 13:23
  • 1
    @thebiggestlebowski I don't think it is. It has been edited from the original where they remade the map in the first example, to use the new delete() syntax, but the original comments were never removed. – TGWaffles Sep 19 '21 at 01:11
117

Copied from Go 1 release notes

In the old language, to delete the entry with key k from the map represented by m, one wrote the statement,

m[k] = value, false

This syntax was a peculiar special case, the only two-to-one assignment. It required passing a value (usually ignored) that is evaluated but discarded, plus a boolean that was nearly always the constant false. It did the job but was odd and a point of contention.

In Go 1, that syntax has gone; instead there is a new built-in function, delete. The call

delete(m, k)

will delete the map entry retrieved by the expression m[k]. There is no return value. Deleting a non-existent entry is a no-op.

Updating: Running go fix will convert expressions of the form m[k] = value, false into delete(m, k) when it is clear that the ignored value can be safely discarded from the program and false refers to the predefined boolean constant. The fix tool will flag other uses of the syntax for inspection by the programmer.

hannson
  • 4,465
  • 8
  • 38
  • 46
  • 1
    What do they mean by no-op? – humble Jul 08 '21 at 13:00
  • 1
    @humble no operation occurs, no error, execution simply continues. I believe it comes from the x86 instruction `NOP` which simply makes execution proceed to the next instruction – Alex Sep 21 '21 at 14:44
  • @Alex Trivia item -- the NOP instruction dates back to at least the early 1950s, with the IBM 701's NoOp instruction. I'm not sure myself if there's a precedent before that. – stevegt Sep 28 '21 at 17:33
  • Why would deleting a non-existent entry be a no-op though? I would assume that it at least does a key lookup, as the compiler could in a general case not know if a key is part of the map. – TheJP Nov 01 '21 at 21:51
  • @TheJP you are correct, but we don't mean a literal `NOP` instruction here. In this case "no-op" simply means that the state of the application will not change in any meaningful way due to the delete(). The delete() has no lasting effect. – Alex Jan 25 '23 at 20:25
102

From Effective Go:

To delete a map entry, use the delete built-in function, whose arguments are the map and the key to be deleted. It's safe to do this even if the key is already absent from the map.

delete(timeZone, "PDT")  // Now on Standard Time
Pang
  • 9,564
  • 146
  • 81
  • 122
György Andrasek
  • 8,187
  • 4
  • 48
  • 76
  • `sessions.go:6: cannot use 0 (type int) as type chan int` –  Nov 15 '09 at 01:10
  • 3
    @Kinopiko: I don't think Jurily meant for the OP to use that code snippet. He just copied an example from the docs. – Isaiah Nov 15 '09 at 03:32
  • 2
    Looks like this has been removed since, getting `assignment count mismatch: 1 = 2 (use delete)` – hayesgm Jun 02 '14 at 03:43
45
delete(sessions, "anykey")

These days, nothing will crash.

coolaj86
  • 74,004
  • 20
  • 105
  • 125
Zippo
  • 15,850
  • 10
  • 60
  • 58
  • 5
    This is now the correct answer, I think. ["If m is nil or there is no such element, delete is a no-op."](https://golang.org/pkg/builtin/#delete) – pnovotnak Sep 21 '16 at 07:10
1

Use make (chan int) instead of nil. The first value has to be the same type that your map holds.

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
}

UPDATE: Corrected my answer.

coolaj86
  • 74,004
  • 20
  • 105
  • 125
Isaiah
  • 4,201
  • 4
  • 27
  • 40