Maps are a very powerful and versatile tool for any programmer in any language. GoLang is no exception.
If you want to know how to use this specific data structure in GoLang, you can use the following 6 simple steps to learn how to create and manipulate maps in your own GoLang projects.
But first, let’s go over what maps are and how they are used.
Understanding GoLang Maps: An Overview
A Map in GoLang is a data structure that allows you to store data indexed by a unique key. It is an efficient way to store and retrieve data that needs to have an unique identifier.
This functionality shines in real-world scenarios where data needs to be quickly accessed, updated, or managed based on unique identifiers, like managing a database of customer records where each customer has a unique ID. Compared to other data structures like arrays or slices, GoLang Maps offers a speedier look-up for values based on keys, which is a significant advantage.
While the idea of Maps isn’t unique to GoLang and is shared across various programming languages like Python or Java, the implementation and syntax may exhibit variances. For instance, the basic syntax of a GoLang Map is map[KeyType]ValueType
, representing the type of keys (KeyType
) and the type of values (ValueType
) the map will hold. This simple yet powerful structure forms the crux of many data management operations in GoLang, making it a vital concept to grasp in this GoLang tutorial.
As we delve deeper into the next sections, you’ll learn the steps to create and manipulate GoLang Maps, unlocking the potential to handle data efficiently in your GoLang projects.
6 Simple Steps to Create a GoLang Map
Creating and manipulating maps is actually quite simple. Let’s delve into this Golang tutorial where we’ll go over what you need to know in order to use them and how to create one.
Map Structure in GoLang
Maps are containers consisting of key-value pairs. The ‘key’ is used as an indexer for the rest of the data, or our ‘value’.
The advantage of a map is that the keys do not have to be sequential and can be inserted in any order. When any key is inserted, the map internally takes care of indexing it in a way that makes future searches fast and efficient.
1. Initializing a Map
Before using a map, you have to initialize it. There are two main ways to do this.
Method 1: Declare and Make
make() is a built-in function of Go that is used to allocate and initialize a complex data structure, such as a map. If you try to use a map before ‘making’ it, an error will occur.
This method declares the map variable, and the map has no entries.
Declare and then make
var map_name map[key_type]value_type
// Any number of lines of code can go here, but you must not use 'map_name' in them
map_name = make(map[kay_type]value_type)
This is useful in case you need to declare the map before allocating and initializing it in some later part of your code.
Declare and make in the same line
var map_name = make(map[key_type]value_type)
Or you can use the short variable declaration operator (‘:=’).
map_name := make(map[key_type]value_type)
The map becomes immediately available to be manipulated further.
Method 2: Declare and Initialize
In this case, the map is declared and immediately filled with any number of entries you require.
map_name := map[key_type]value_type{
key1: value1,
key2: value2, // remember to always use a comma, even in the last key-value pair
}
Practical Example
We’ll be doing a practical example by developing a simple program that keeps track of the patrons of a library. We’ll be using a map to store our library’s patrons. Their Patron ID will be our ‘key’, and their name our ‘value’. The patron ID will be a simple integer, and their name a string.
Since we already want to have some patrons in our library, we’ll declare and initialize straight away.
Mr. Terrence and Ms. Evelyn work at the library and also use it, so they are our first patrons to be registered.
We’ll import the fmt package from now on so we can print our map’s contents to the screen.
Method 1
package main
import "fmt"
func main() {
patrons := make(map[int]string)
patrons[0] = "Terrence"
patrons[1] = "Evelyn"
fmt.Println(patrons)
}
The output is:
map[0:Terrence 1:Evelyn]
Method 2
package main
import "fmt"
func main() {
patrons := map[int]string{
0: "Terrence",
1: "Evelyn",
}
fmt.Println(patrons)
}
The output is:
map[0:Terrence 1:Evelyn]
2. Adding to a Map
Adding to a map is simple. All you need to do is assign a value to a key on a map. Remember that keys are unique and cannot repeat. If the key already exists, the assignment will replace the existing value.
map_name[key] = value
Practical Example
New patrons are now registering in our library, so we’ll add them to our map and give them unique IDs.
package main
import "fmt"
func main() {
patrons := map[int]string{
0: "Terrence",
1: "Evelyn",
}
patrons[2] = "Jonathan"
patrons[3] = "Rick"
fmt.Println(patrons)
}
The output is:
map[0:Terrence 1:Evelyn 2:Jonathan 3:Rick]
3. Retrieving a Value from a Golang Map
If you want to retrieve a value from a map, you do it using the key, like so:
map_name[key]
Practical Example
Let’s see who our patron 1 is.
package main
import "fmt"
func main() {
patrons := map[int]string{
0: "Terrence",
1: "Evelyn",
}
fmt.Printf("Who is our Patron #%d? %s!", 1, patrons[1])
}
The output is:
Who is our Patron #1? Evelyn!
4. Iterating a Map
Iterating maps is usually done with a for loop combined with the range keyword.
for key, value := range map_name {
// Process each key-value pair. You have access to both the 'key' and the 'value'.
}
If you don’t care about a specific part of the key-value pair, you can use the blank identifier (‘_’) instead of declaring a variable.
for _, value := range map_name {
// Process each 'value' on the map. The key is automatically discarded.
}
for key, _ := range map_name {
// Process each 'key' on the map. The value is automatically discarded.
}
Practical Example
We’ve seen that you can print a whole map at once using fmt.Println(), but let’s format it a little better by ourselves, and also provide some more information about our data.
package main
import "fmt"
func main() {
patrons := map[int]string{
0: "Terrence",
1: "Evelyn",
}
fmt.Printf("--- Our Patrons ---\n")
for id, name := range patrons {
fmt.Printf("ID: %d , Name: %s\n", id, name)
}
fmt.Printf("\n\n--- Used IDs ---\n")
for id, _ := range patrons {
fmt.Printf("%d, ", id)
}
fmt.Printf("\n\n--- Our Patrons' Names ---\n")
for _, name := range patrons {
fmt.Printf("%s, ", name)
}
}
The output is:
--- Our Patrons ---
ID: 0 , Name: Terrence
ID: 1 , Name: Evelyn
--- Used IDs ---
1, 0,
--- Our Patrons' Names ---
Evelyn, Terrence,
5. Checking if an entry exists on a Map
When we try to get a value from a map, it also returns a boolean that tells us if the key exists in the map or not. We can then use it to make checks and have code ready that is tailored to either scenario where the key exists or doesn’t.
returned_value, boolean_exists := map_name[key]
if(boolean_exists){
// You can now use 'returned_value'
}
If the value is irrelevant to what you want to do and you just want to check that the key exists on the map, you can use the blank identifier.
_, boolean_exists := map_name[key]
if(boolean_exists){
// You know that the key exists on the map, but not the associated value
}
Practical Example
Let’s check our patrons and see if an ID is being used and if so, by whom.
package main
import "fmt"
func main() {
patrons := map[int]string{
0: "Terrence",
1: "Evelyn",
}
patron1_name, patron1_exists := patrons[1]
if(patron1_exists){
fmt.Printf("Patron #%d exists and is named %s.\n", 1, patron1_name)
} else {
fmt.Printf("Patron #%d does not exist.\n", 1)
}
_, patron2_exists := patrons[2]
if(patron2_exists){
fmt.Printf("Patron #%d exists.\n", 2)
} else {
fmt.Printf("Patron #%d does not exist.\n", 2)
}
}
The output is:
Patron #1 exists and is named Evelyn.
Patron #2 does not exist.
6. Removing an entry from a Golang Map
To remove a key-value pair on a map, all you need to do is use the built-in function delete().
delete(map_name, key)
Practical Example
Mr. Terrence is moving away and unfortunately will no longer be working at the library. As such, we need to remove him from our patrons.
package main
import "fmt"
func main() {
patrons := map[int]string{
0: "Terrence",
1: "Evelyn",
}
fmt.Println("Before Mr. Terrence Leaves:")
fmt.Println(patrons, "\n")
delete(patrons, 0)
fmt.Println("After Mr. Terrence Leaves:")
fmt.Println(patrons, "\n")
}
The output is:
Before Mr. Terrence Leaves:
map[0:Terrence 1:Evelyn]
After Mr. Terrence Leaves:
map[1:Evelyn]
Remember: GoLang Maps are reference types
This is useful to remember if you’re assigning a map to another variable. Manipulating that new variable will also change the original map.
map_name := make(map[key_type]value_type)
map_copy := map_name
map_copy[key] = value
// Both 'map_name' and 'map_copy' now have an entry [key:value]
Practical Example
Imagine we wanted to have separate dedicated lists for our patrons and our staff, but still include our staff as our patrons, since they also use the library.
package main
import "fmt"
func main() {
staff := map[int]string{
0: "Terrence",
1: "Evelyn",
}
patrons := staff
patrons [2] = "Jonathan"
patrons [3] = "Rick"
fmt.Println("Our Staff:")
fmt.Println(staff, "\n")
fmt.Println("Our Patrons:")
fmt.Println(patrons, "\n")
}
The output is:
Our Staff:
map[0:Terrence 1:Evelyn 2:Jonathan 3:Rick]
Our Patrons:
map[0:Terrence 1:Evelyn 2:Jonathan 3:Rick]
This clearly would not work. We’d need to have two separate lists with repeat entries.
package main
import "fmt"
func main() {
staff := map[int]string{
0: "Terrence",
1: "Evelyn",
}
patrons := make(map[int]string)
patrons [0] = "Terrence"
patrons [1] = "Evelyn"
patrons [2] = "Jonathan"
patrons [3] = "Rick"
fmt.Println("Our Staff:")
fmt.Println(staff, "\n")
fmt.Println("Our Patrons:")
fmt.Println(patrons, "\n")
}
The output is:
Our Staff:
map[0:Terrence 1:Evelyn]
Our Patrons:
map[0:Terrence 1:Evelyn 2:Jonathan 3:Rick]
Common Mistakes When Working with GoLang Maps and How to Avoid Them
Working with maps in GoLang can be straightforward once you grasp the basics, but there are common pitfalls that developers, especially those new to GoLang, may stumble upon. Here’s a roundup of some common mistakes and how you can sidestep them:
1. Not Initializing Maps Before Use:
GoLang maps need to be initialized before they can be used.
- Solution: Always initialize your maps using the
make
function or a map literal.
go
// Correct way:
myMap := make(map[string]int)
// or
myMap := map[string]int{}
2. Assuming Order in Map Iteration:
Maps in GoLang do not maintain an order of elements. Assuming an order during iteration is a mistake.
- Solution: If order is crucial, consider using a slice to maintain order or a sorted map implementation.
go
// If order is needed, use a slice:
keys := []string{}
for key := range myMap {
keys = append(keys, key)
}
sort.Strings(keys) // Now keys are sorted
3. Modifying Maps During Iteration:
Modifying a map while iterating over it can cause errors.
- Solution: Collect the keys or values you want to modify in a separate slice, then iterate over that slice to make changes to the map.
go
// Collect keys:
keysToModify := []string{}
for key, value := range myMap {
if value > 10 {
keysToModify = append(keysToModify, key)
}
}
// Modify map:
for _, key := range keysToModify {
myMap[key] += 10
}
4. Ignoring the ok
Check:
When accessing an element, it’s good practice to perform an ok
check to see if the key exists in the map to avoid zero-value errors.
- Solution: Always perform the
ok
check when accessing map elements.
go
// Correct way:
value, ok := myMap["someKey"]
if ok {
// Key exists
} else {
// Key does not exist
}
By being aware of these common missteps and applying the outlined solutions, you’ll be on a surer footing when working with GoLang maps, making your coding journey smoother and bug-free.
Conclusion
Maps are extremely versatile tools that help you index and search through data efficiently and easily. We hope we’ve given you a comprehensive primer on how Go Maps work and how you can use them in your projects.
Go is a very easy-to-use language that is growing rapidly in terms of usage by many high profile companies. If you’re looking to hire Go developers, DistantJob can help you find the perfect fit for your needs.