Check if a Map Contains a Certain Key in Go

Clive B.
—The Problem
You don’t know how to check whether a map contains a given key in Go.
The Solution
Go allows a two-value assignment when reading from a map:
- The first assignment variable is the value associated with the key.
- The second variable is a boolean that is set to
trueif the key exists.
If you just want to read the value from a Go map, only assign to one variable (value):
package main import "fmt" func main() { example := map[int]string{ 42: "forty-two", } value := example[42] fmt.Println(value) // Prints "forty-two". }
Include the second variable (exists) to check whether the map contains a specific value:
func main() { example := map[int]string{ 42: "forty-two", } value, exists := example[42] fmt.Println(value, exists) // Prints "forty-two true". value, exists = example[43] fmt.Println(value, exists) // Prints " false". }
In this example, the variable value is set to "", which is the zero value for the string type, because Go maps always return the zero value of the value type (in this case, string).
If you only want to check for the existence of a key, you can throw away the value:
func main() { example := map[int]string{ 42: "forty-two", } _, exists := example[42] fmt.Println(exists) // Prints "true". }
Maps As Sets
Go doesn’t have a set implementation as part of the runtime, so maps are often used to fill this gap. Since maps always return the zero value on read, you can easily make something that approximates a set.
Create a set by assigning your elements as keys and setting the value to true, then check for it contains the key:
package main import "fmt" func main() { set := map[string]bool{ "forty-two": true, } value, contains := set["forty-two"] fmt.Println(value, contains) // Prints "true true". }
The above example uses two variables to check the value and existence of a specific key. However, you don’t need to assign both variables during read, because the value of elements in the map will always be true and the zero boolean value (false) will be returned for any elements that aren’t in the map:
func main() { set := map[string]bool{ "forty-two": true, } fmt.Println(set["forty-two"]) // Prints "true". fmt.Println(set["forty-three"]) // Prints "false". }
There’s one caveat: If you’re trying to squeeze performance out of a set, it’s more memory efficient to use an empty struct as the value type, because it uses zero memory.
Further Reading
- The Go maps in action blog post
- The zero value in the Go Spec
- The empty struct by Dave Cheney
- SentryGo Error Tracking and Performance Monitoring
- Syntax.fmListen to the Syntax Podcast
- Listen to the Syntax Podcast
![Syntax.fm logo]()
Tasty treats for web developers brought to you by Sentry. Get tips and tricks from Wes Bos and Scott Tolinski.
SEE EPISODES
Considered “not bad” by 4 million developers and more than 150,000 organizations worldwide, Sentry provides code-level observability to many of the world’s best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.
