- Key features & common operations for Maps
- Key-value pairs
- NOT Thread safe
- Official docs
- Pass-by-address-value
- All things pass by value
- maps, slices, channels, functions are passed by "address" value (like a pointer)
- If you pass a
map
to a function/method, callee can mutate the map
- Key can be any type with equality operator defined
- eg. string, integer, float, pointer, struct, array, most interfaces
- NOT slices
- Like
HashMap
in java
- Via literal
var m = map[string]int{
"alice": 30,
"janet": 28,
"olivia": 42,
}
- Via
make
m := make(map[string]int)
m := map[string]int{
"a": 7,
"b": 5,
}
delete(m, "b")
delete(m, "notPresent") // noop
fmt.Println(m) // map[a:1]
- when value missing, returns zero-value
m := map[string]int{
"a": 7,
"b": 5,
}
fmt.Println(m["a"]) // 7
fmt.Println(m["c"]) // 0 zero value, not robust :-(
// -- Better pattern:
value, ok := m["c"]
if ok { // ok == map-contains-c
fmt.Println(value)
}
if value, found := m["a"]; found {
fmt.Println(value)
}
- iteration order is random
for key, value := range someMap {
someMap[key] = value
}
// -- keys only
for k := range someMap {
// do something with k
}
// -- values only
for _, v := range someMap {
fmt.Println(v)
}
keys := make([]keyType, len(m))
for k := range m {
keys = append(keys, k)
}
- Alternative: https://pkg.go.dev/golang.org/x/exp/maps#Keys
src := map[string]int {
"a": 7,
}
dest := make(map[string]int, len(src))
for k, v := range src {
dest[k] = v
}
// Use a sync.Mutex when concurrent
if _, exists := m[key]; !exists {
m[key] = "foo"
}
m := make(...)
fmt.Printf("Data: %#v\n", m)
- structs can only be keys if all its fields are comparable
- eg.
url.URL
works as a key
- Only use
sync.Map
when you can demonstrate high lock contention
- If you must mutate the map value (structs values), use pointer
- eg.
map[string]*myStruct
- If your value is complicated, use a type alias
- Gotcha: Maps are not comparable with
==
- Official docs
- practical-go-lessons
- go101
- gobyexample.com
- Language spec
- Syncronized map
- https://golangbyexample.com/allowed-key-and-value-types-golang/