The solution #
To check if a key exists in a map use the "comma ok" pattern, value, ok := yourMap[key]
. When getting a value from a map
Go can return a second value which is a bool
denoting if the key exists inside the map for not.
Here is an example.
package main import "fmt" func main() { myMap := map[string]string{ "key": "value", "hello": "world", } value, ok := myMap["dog"] fmt.Println(ok) // prints 'false' fmt.Println(value) // prints '' (empty string) }
main.go
You are fetching the value for key dog
in the map which doesn't exists. The value of ok
will tell you if the key exists inside the map.
nil Map
This also works in case the map is nil
.
package main import "fmt" func main() { var myMap map[string]string // map is `nil` fmt.Println(myMap == nil) // Prints 'true' value, ok := myMap["dog"] fmt.Println(ok) // prints 'false' fmt.Println(value) // prints '' (empty string) }
main.go
Below are some more interesting facts about map
s in Go that you may or may not know.
Passing maps into functions #
When you are passing a map to a function you are not passing a copy of the map, you are passing a copy of the pointer that points to the map, so essetially the function would have access to the same map. Any changes made to the map by the function will reflect in the caller.
package main import "fmt" func main() { myMap := map[string]string{ "key": "value", } fmt.Println(myMap) // Prints 'map[key:value]' DoWork(myMap) fmt.Println(myMap) // Prints 'map[dog:cat key:value]' } func DoWork(m map[string]string) { m["dog"] = "cat" }
main.go
The DoWork
function ends up adding a new entry(dog: cat
) to the myMap
.
Implementing a set using a map #
Go doesn't have a set type, but not to worry as implementing a set using a map
is very easy. We need a map[T]bool
type of map where T
is the type of set you looking for.
A set mainly has 3 functions Add
(to add values to set), Contains
(check if value existins in set) and Remove
(remove a value from a set).
Let's design a new type in Go called StringSet
.
type StringSet struct {
m map[string]bool // underlying map holding set values
}
func NewStringSet() StringSet {
return StringSet{
m: make(map[string]bool),
}
}
func (s StringSet) Add(value string) {
s.m[value] = true
}
func (s StringSet) Contains(value string) bool {
return s.m[value]
}
func (s StringSet) Remove(value string) {
delete(s.m, value)
}
Using the above StringSet
.
package main
import "fmt"
func main() {
set := NewStringSet()
set.Add("1")
set.Add("2")
fmt.Println(set.Contains("1")) // Prints 'true'
fmt.Println(set.Contains("3")) // Prints 'false'
set.Remove("1")
fmt.Println(set.Contains("1")) // Prints 'false'
}
Keys allowed in a map #
Go only allows types to be used as keys that are comparable. These comparable types include bool
, int
, string
, array
(not slices), interface
, struct
.
Some types that cannot be used as keys of a map include slice
, functions
, map
. If you try to use these types as keys of map as below:
package main
import "fmt"
func main() {
myMap := make(map[[]int]string) // ā will not compile
fmt.Println(myMap)
}
you will get the compile error ./main.go:6:20: invalid map key type []int
.
Thank you for reading this article šš» hope you learned something new.