Video Coming Soon...
18: The Type System: Maps
WARNING This exercise is in DRAFT status, so there may be errors. If you find any, please email me at help@learncodethehardway.com so I can fix them.
After array
the map
data structure should be easy. A map
is a structure that "maps" a key to a value. You can think of it like a "dynamic struct
" that lets you have any number of fields. For example, if I have a struct
like this:
type Person struct {
Name string
Age int
}
a_person := Person{"Zed", 51}
I could instead use a map
to hold the same data:
a_person["Name"] = "Zed"
a_person["Age"] = 51
A map
has the advantage that is can use data as its keys, not just compiled words like Name
above. That lets you read data from a config file and use it to build a map
of key=value pairs without having to know what's in the config. You could also use an int32
as a key if that's what your data needs.
How to Create a map
You create a map
in two ways similar to an array
:
var flowers map[string]int
This creates a map
that uses string
for keys and int
for values. If you try to use this map though you'll get an error because it is a nil map
, meaning it's not actually ready yet:
$ ./ex18
panic: assignment to entry in nil map
To use a map
you have to use make()
to create it like so:
var flowers map[string]int
flowers = make(map[string]int)
Now you can use flowers
, but this is really annoying. It's more convenient to use the :=
like with other variables:
flowers := make(map[string]int)
That does both the var
and make the map in one move.
Putting Things Into map
To add data to your map you use the same syntax as with an array
, but you can use the [type]
as your key (in our case string
):
flowers := make(map[string]int)
flowers["Roses"] = 10
flowers["Peonies"] = 4
flowers["Garden Roses"] = 5
NOTE If you've ever used JSON or YAML then this is the same as the maps there, but you can use more than just strings for the keys.
The Key Rules
You can use many types as the keys, but they have to follow certain rules:
- A key can be anything that can compare with
==
or!=
. - This means you can't use functions, maps, or slices as keys because those are not "comparable."
- There's a list of comparable types if you need.
- If you plan on exporting the map (see later exercise) then you should only use
string
as a key since most languages have this restriction.
It's safest to simply use the basic types (int
, float64
, string
, etc.) so you don't have to worry about the rules or what's "comparable."
The maps
Package
Just like with slices
there's a maps package that has extra functions to help handle map
types.
Built-In Functions for map
The full list of built-in functions is available online. These are "built into Go" so you don't import this package. Here's the ones that help with map
:
len(m)
-- Get the number of elements in the map (length).delete(m, key)
-- Delete the element atkey
from themap
.clear(m)
-- Clear themap
of contents.make(T)
-- Make a map of type T.
The Code
As with the previous exercise I'm not doing a breakdown of this one since it's so similar to the previous and there should be nothing new except for the concepts covered in this exercise. If you did little experiments as you studied this exercise then this should have nothing new.
View Source file ex18/main.go Only
package main
import (
"fmt"
)
type Animal struct {
Name string
Age int
Species string
Weight float64
}
func main() {
owners := make(map[string]Animal)
owners["Alex"] = Animal{"Doug", 5, "Dog", 25.0}
owners["Mark"] = Animal{"Catherine", 1, "Cat", 2}
owners["Debbie"] = Animal{"Gary", 1, "Goldfish", 0.1}
owners["Xan"] = Animal{"Percy", 10, "Python", 50.0}
for owner, pet := range owners {
fmt.Println(owner, "owns", pet)
}
fmt.Println("before delete", owners["Alex"])
delete(owners, "Alex")
alex, ok := owners["Alex"]
fmt.Println("after delete", alex, "is there", ok)
}
The Practice
- Break It -- As usual, try to add things to
nil map
. You can also try to add keys that are not comparable. Try using a function as a key to see what error you get. - Change It -- Spend some time to really work with the
map
type and use it. Try all the operations likedelete()
andclear()
. - Recreate It -- Once again, you should try to recreate this from notes you write about it. You're also getting to a point where that may be boring, so you could also devise your own idea and try to create it from your own descriptions.
Study Drills
- Read the documentation for map and make().
- Go through the maps package and try out the examples there.
- Using what you know about reading input from the last module, can you store a user's input into a
map
?
Register for Learn Go the Hard Way
Register today for the course and get the all currently available videos and lessons, plus all future modules for no extra charge.