Golang is a type safe language which sets 0 as the value of undefined
variables automatically. So, if you are checking the existence of a key in map, you can’t simply use if
condition. Because 0 is also a valid value and it doesn’t distinguish between a non-existing and existing value.
Problem
Suppose you have a map –
package main import {"fmt"} func main() { attended := map[string]string{ "ironman": "Marvel", "captain_america": "Marvel", "thor": "Marvel", "superman": "DC", "batman": "DC", "flash": "DC", } }
Here we have created a string:string
map of superheroes and their franchise. If we try to use a non-existing key, then golang will not throw an error, else it will return an empty string. This makes it hard to understand if the key exists or not.
package main import {"fmt"} func main() { attended := map[string]string{ "ironman": "Marvel", "captain_america": "Marvel", "thor": "Marvel", "superman": "DC", "batman": "DC", "flash": "DC", } fmt.Println(attended["black_widow"]) }
In the above code, although black_widow
doesn’t exist in the map but golang will print empty line. If the values were of type int
, then it would have returned 0. Similarly for bool
, it would have returned false
.
Solution
So, how can we know about the existence of a key? Well, for such cases golang provides , ok
syntax. According to the golang maps documentation –
For obvious reasons this is called the “comma ok” idiom. In this example, if
tz
is present,seconds
will be set appropriately andok
will be true; if not,seconds
will be set to zero andok
will be false. Here’s a function that puts it together with a nice error report:
func offset(tz string) int {
if seconds, ok := timeZone[tz]; ok {
return seconds
}
log.Println("unknown time zone:", tz)
return 0
}
To test for presence in the map without worrying about the actual value, you can use the blank identifier (
_
) in place of the usual variable for the value.
_, present := timeZone[tz]
Check this code –
package main import "fmt" func main() { attended := map[string]string{ "ironman": "Marvel", "captain_america": "Marvel", "thor": "Marvel", "superman": "DC", "batman": "DC", "flash": "DC", } if _, ok:= attended["black_widow"]; ok { fmt.Println("Black Widow is in map") } else { fmt.Println("Black Widow is not in map") } }
Note that we are using _
in if
condition so that golang do not show warning regarding unused variable.