Index expression special cases for maps

November 17, 2023

Today we’re finishing up our discussion of…

Index expressions

So far, we’ve discussed what index expressions are, and specific rules as they apply to:

Otherwise a[x] is illegal.

But there are two more special cases to consider for maps:

An index expression on a map a of type map[K]V used in an assignment statement or initialization of the special form

v, ok = a[x]
v, ok := a[x]
var v, ok = a[x]

yields an additional untyped boolean value. The value of ok is true if the key x is present in the map, and false otherwise.

This is particularly useful to distinguish between an existing value in a map that happens to be set to the zero value. Consider:

m := map[int]string{
  1: "foo",
  2: "",

x := m[1] // x == "foo"
y := m[2] // y == ""
z := m[3] // z == "", even though key 3 does not exist in the map

yy, ok := m[2] // y == "", ok == true
zz, ok := m[3] // z == "", ok == false

Assigning to an element of a nil map causes a run-time panic.

So while reading from a nil map is permitted, assignment to one is not.

var m map[int]int // m is of type map[int]int, but nil
x := m[3] // x == 0, but the expression is valid
m[3] = 12 // run-time panic

Quotes from The Go Programming Language Specification Version of August 2, 2023

Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content

Index expressions for type parameters

Index expressions … For a of type parameter type P: So just a reminder what this means: We’re talking about index expressions for different data types. And we’re going through different interpretations of the expression a[x]. In this example, a is of a “type parameter” type, represented by P. And as a further reminder, a type parameter looks something like [X any] or [Y ~int]. So for this example, we’re assuming that we have [P <.

Index expressions for maps

Index expressions … For a of map type M: x’s type must be assignable to the key type of M No surprise here. The key must be assignable to the key type. But notably, it needn’t be of an identical type, so long as it is assignable to the key type. m := map[string]int{ "foo": 3, "bar": 12, } m[string("foo")] // string("foo") is explicitly of type string, so assignable. m["foo"] // Untyped constant string "foo" is assignable to type `string` type Key string k := Key("bar") m[k] // k is of type Key, not assignable to type string without explicit conversion if the map contains an entry with key x, a[x] is the map element with key x and the type of a[x] is the element type of M This should be intuitive.

Index expressions for slices and strings

Index expressions … For a of slice type S: if x is out of range at run time, a run-time panic occurs a[x] is the slice element at index x and the type of a[x] is the element type of S This is essentially identical to the rules for arrays, except that there’s no possibility of a compile-time error when using a constant index, since the length of a slice is not known at compilation time.