Go

Is it safe to add or delete map entries while ranging over the map?

Question 58MediumGo 1.22 to 1.25

Yes, within one goroutine. The spec defines the behaviour:

  • Deleting an entry that has not been reached yet means it will not be produced. Deleting the current key is always safe. This is the idiomatic way to filter a map in place.
  • Adding an entry during iteration means it may or may not be produced. The result can differ between runs.
m := map[int]bool{1: true, 2: false, 3: true, 4: false}

// Safe in-place filter
for k, v := range m {
	if !v {
		delete(m, k)
	}
}
fmt.Println(len(m)) // 2

// Library form (Go 1.21)
maps.DeleteFunc(m, func(k int, v bool) bool { return k > 2 })

// Nondeterministic: new keys may be visited
n := map[int]int{0: 0}
count := 0
for k := range n {
	if count++; count > 100 {
		break
	}
	n[k+1] = k + 1
}
fmt.Println(count) // varies between runs

Interviewer angle: contrast this with Java's ConcurrentModificationException. Go does not fail fast here. Across goroutines, though, any write during a range is a data race, and the runtime may kill the process ("concurrent map iteration and map write").

More on Arrays, Slices, Maps & Strings

All 37 Arrays, Slices, Maps & Strings questions