Intro
Maps are somewhat similar to what other languages call “dictionaries” or “hashes”. A map maps keys to values.
Here are some points to look at:
Mapsallows us to quickly access to anelement/valueusing aunique key.Map keysmust beuniquebecause otherwise it can’t find the correspondingvalues/elements.- The types of
Map KeysandValues in Mapscan bedifferent. - A
Map Keymust be acomparable type. You can read more about comparing on the Golang spec: comparing. - All
Map KeysandMap Valuesmustbelongto theircorresponding types. Theycan't be mixed up. - A
Map Variable (or a Value)is nothing but apointerto aMap Header Valuein thememory. - A
Map Valueonly contains thememory addressof aMap Header.
Creating Maps
Maps can be created in two ways:
1) Using map literals
package main
import "fmt"
func main (){
m := map[string]string{ //here we are declaring the key to be of type string and the value to be of type string
"Picard":"The next generation",
"Janeway":"Voyager",
"Kirk":"Star Trek",
}
fmt.Println(m)
}
Again this is very similar to object creation in javascript. Remove the types and it is exactly the same.
Maps can contain any valid type. When using a custom type in a map, you can omit the type name in a map literal definition:
package main
import "fmt"
type Location struct {
Lat, Lng float64
}
func main() {
m := map[string]Location{
"Bell Labs": {40.68433, -74.39967},
"Google": {37.42202, -122.08408},
}
fmt.Println(m)
}
2) With the make keyword
The make built-in function allocates and initializes an object of type slice, map, or chan (only).
package main
import "fmt"
func main (){
m := make(map[string]string,3) // The second argument here is the initial size of the map (optional).
m["Picard"] = "The next generation"
m["Janeway"] = "Voyager"
m["Kirk"] = "Star Trek"
fmt.Println(m)
}
The only reason to use the make key word is if you want to decide the size of the map before hand.
Lets go through some common actions with maps.
Playing with Map
Adding values
m[key] = elem
Checking if a key exists in a map
elem, ok = m[key]
if ok { // key is in map
do something with elem
}
Retrieve an element
elem = m[key]
Delete an element
delete(m, key)
Get length of map
length = len(m)
Iterating through a map
for key,val := range m{ //notice the range key word we will talk more about this
fmt.Printf("map has key %s and value %s \n",key,val)
}
Example - Retreive values from map
package main
import "fmt"
func main (){
m := map[string]string{
"Picard":"The next generation",
"Janeway":"Voyager",
"Kirk":"Star Trek",
}
if v,ok := m["Picard"]; ok{ // in this case ok is a bool that will be true if the key exists.
fmt.Println(v)
}
if v := m["Picard"]; v != ""{ // in this case you have to assert something about the returned value. I prefer the example above.
fmt.Println(v)
}
if _,ok := m["not here"]; !ok{ //notice the _ here this is used to ignore a return value
fmt.Println("no key with that name")
}
}
Example - Iterating through a map
package main
import "fmt"
func main (){
m := map[string]string{
"Picard":"The next generation",
"Janeway":"Voyager",
"Kirk":"Star Trek",
}
for key,val := range m{ //notice the range key word we will talk more about this
fmt.Printf("map has key %s and value %s \n",key,val)
}
}
Range So we saw the range keyword above. A range clause provides a way to iterate over an array, slice, string, map, or channel (more on channels in the future). It is only used in conjunction with a for loop. One thing to note is that when you use the range key word, for each loop, it copies the current key and value into the vars. This means that if you change the value in the loop it will not be reflected in the map or slice.
Example - Get the size of a map
To find out the size of a map (i.e the number of keys it has) we use the builtin len function.
package main
import "fmt"
func main (){
m := map[string]string{
"Picard":"The next generation",
"Janeway":"Voyager",
"Kirk":"Star Trek",
}
fmt.Println(len(m)) //outputs 3
}
Example - Deleting items from a map
To Delete an item from a map use the buit in delete function:
package main
import "fmt"
func main (){
m := map[string]string{
"Picard":"The next generation",
"Janeway":"Voyager",
"Kirk":"Star Trek",
}
delete(m,"Picard") //delete takes the map as the first arg and the key as the second
fmt.Println(m)
}