How to check if map key exists in Go

Maps are unordered collections of data in Go which may contain several properties each with a key and value. The strength of a map is its ability to retrieve data quickly based on the key. In this code snippet, we are going to look at how you can check to see if a key exists within a map in Go.

When you try to access the value of a key that does not exist on map, the zero value for the type of the entries in the map is what you get back. This is not very useful for distinguishing between a key that exists in the map but is explicitly assigned to the zero value of the type, and one that does not exists at all.

func main() {
	m1 := map[string]int{
		"a": 0,
		"b": 1,
		"c": 2,
	}

	// "a" exists in map
	v1 := m1["a"]
	fmt.Println(v1) // 0

	// "f" does not exist in the map
	v2 := m1["f"]
	fmt.Println(v2) // 0

	// How to distinguish between the two?
}

In such situations, it is necessary to use what is known as an index expression to check if the specified key exists. Here’s how it works:

func main() {
	m1 := map[string]int{
		"a": 1,
		"b": 2,
		"c": 3,
	}

	if v, exists := m1["a"]; exists {
		// The "a" key exists in map
		fmt.Println(v) // 1
	} else {
		// if "a" does not exist
		fmt.Println("Key not found")
	} // `v` and `exists` go out of scope here
}

if statements in Go can include a condition and an initialisation statement as shown above. The v and exists variables are bound to the scope of the if block (including the any else or else if blocks) so you cannot access them outside this block. If you need to access the value outside the if block, you need to declare the variables outside as well:

func main() {
	m1 := map[string]int{
		"a": 1,
		"b": 2,
		"c": 3,
	}

	v, exists := m1["a"]
	if exists {
		// The "a" key exists in map
		fmt.Println(v) // 1
	} else {
		// "a" does not exist
		m1["a"] = 40
	}
	// `v` and `exists` remain accessible
}

The exists variable will be true if the specified key exists in the map. Otherwise, it will be false. Some people prefer to use ok or found as the naming convention for the second variable instead of exists:

v, ok := m1["a"]
if ok {
	fmt.Println(v)
}

If you only want to check if a key exists without caring about its actual value, just assign the value to the blank operator (_). This has the effect of discarding the value.

_, ok := m1["a"]
if ok {
	// do something
}

Thanks for reading, and happy coding!