# Go Check if a Map Contains a Certain Key Value

> Use the two-value comma-ok form when reading from a Go map to check whether a key exists, and see how the same idiom lets maps double as sets

**URL:** https://sentry.io/answers/check-if-a-map-contains-a-certain-key-in-go/

---

## 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 `true` if the key exists.

If you just want to read the value from a Go map, only assign to one variable (`value`):

```go
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:

```go
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](https://go.dev/ref/spec#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:

```go
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:

```go
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:

```go
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](https://dave.cheney.net/2014/03/25/the-empty-struct).

### Further Reading

- The [Go maps in action](https://go.dev/blog/maps) blog post
- [The zero value](https://go.dev/ref/spec#The_zero_value) in the Go Spec
- [The empty struct](https://dave.cheney.net/2014/03/25/the-empty-struct) by Dave Cheney

---

*Source: [sentry.io/answers/check-if-a-map-contains-a-certain-key-in-go/](https://sentry.io/answers/check-if-a-map-contains-a-certain-key-in-go/)*
