Skip to content

Latest commit

 

History

History
166 lines (130 loc) · 3.15 KB

collections.maps.md

File metadata and controls

166 lines (130 loc) · 3.15 KB

Overview

  1. Key features & common operations for Maps

Key Concepts

  1. Key-value pairs
  2. NOT Thread safe
    1. Official docs
  3. Pass-by-address-value
    1. All things pass by value
    2. maps, slices, channels, functions are passed by "address" value (like a pointer)
    3. If you pass a map to a function/method, callee can mutate the map
  4. Key can be any type with equality operator defined
    1. eg. string, integer, float, pointer, struct, array, most interfaces
    2. NOT slices
  5. Like HashMap in java

Create

  1. Via literal
var m = map[string]int{
  "alice": 30,
  "janet": 28,
  "olivia": 42,
}
  1. Via make
m := make(map[string]int)

Size

theSize := len(myMap)

Insert/Update

myMap["foo"] = 7

Remove

m := map[string]int{
  "a": 7,
  "b": 5,
}

delete(m, "b")
delete(m, "notPresent") // noop

fmt.Println(m) // map[a:1]

Retrieve

  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)
}

Check for key

if value, found := m["a"]; found {
    fmt.Println(value)
}

Iterate

  1. 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)
}

Get Keys

keys := make([]keyType, len(m))
for k := range m {
    keys = append(keys, k)
}
  1. Alternative: https://pkg.go.dev/golang.org/x/exp/maps#Keys

Shallow copy

src := map[string]int {
    "a": 7,
}

dest := make(map[string]int, len(src))
for k, v := range src {
    dest[k] = v
}

Put-if-absent

// Use a sync.Mutex when concurrent
if _, exists := m[key]; !exists {
    m[key] = "foo"
}

Sort

Print

m := make(...)
fmt.Printf("Data: %#v\n", m)

Custom keys

  1. structs can only be keys if all its fields are comparable
    1. eg. url.URL works as a key

Idioms

  1. Only use sync.Map when you can demonstrate high lock contention
  2. If you must mutate the map value (structs values), use pointer
    1. eg. map[string]*myStruct
  3. If your value is complicated, use a type alias
  4. Gotcha: Maps are not comparable with ==

Other Resources

  1. Official docs
  2. practical-go-lessons
  3. go101
  4. gobyexample.com
  5. Language spec
  6. Syncronized map
  7. https://golangbyexample.com/allowed-key-and-value-types-golang/