Golang map keyword
last modified May 7, 2025
This tutorial explains how to use the map
keyword in Go. We'll
cover map basics with practical examples of creating and manipulating maps.
The map is a built-in data type that associates keys with values. It's Go's implementation of a hash table or dictionary in other languages.
In Go, maps are unordered collections where each key must be unique. They provide efficient lookup, insertion, and deletion operations.
Basic map declaration and initialization
This example shows how to declare and initialize a map with string keys and integer values. It demonstrates basic map operations.
package main import "fmt" func main() { // Declare and initialize a map ages := map[string]int{ "Alice": 25, "Bob": 30, "Carol": 28, } // Access a value fmt.Println("Alice's age:", ages["Alice"]) // Add a new key-value pair ages["Dave"] = 32 // Update a value ages["Bob"] = 31 // Delete a key delete(ages, "Carol") fmt.Println("Updated map:", ages) }
The map is initialized with three key-value pairs. We demonstrate accessing, adding, updating, and deleting elements. Maps are dynamic and grow as needed.
Checking for key existence
This example shows how to check if a key exists in a map. Go provides a special syntax for this check.
package main import "fmt" func main() { colors := map[string]string{ "red": "#FF0000", "green": "#00FF00", "blue": "#0000FF", } // Check if key exists value, exists := colors["red"] if exists { fmt.Println("Red's hex code:", value) } else { fmt.Println("Red not found") } // Check for non-existent key value, exists = colors["yellow"] if exists { fmt.Println("Yellow's hex code:", value) } else { fmt.Println("Yellow not found") } }
The two-value assignment checks for key existence. The second boolean value indicates if the key exists. This prevents ambiguity with zero values.
Iterating over a map
Maps can be iterated using the range keyword. This example shows how to loop through all key-value pairs.
package main import "fmt" func main() { capitals := map[string]string{ "USA": "Washington D.C.", "France": "Paris", "Japan": "Tokyo", "India": "New Delhi", } // Iterate over all key-value pairs for country, capital := range capitals { fmt.Printf("The capital of %s is %s\n", country, capital) } // Iterate just over keys for country := range capitals { fmt.Println("Country:", country) } }
The range keyword returns both key and value. Order is not guaranteed as maps are unordered collections. Keys can be accessed alone by omitting the value.
Map of slices
This example demonstrates a map where each value is a slice. It shows how to work with more complex map structures.
package main import "fmt" func main() { // Map of string slices classes := map[string][]string{ "math": {"algebra", "calculus", "geometry"}, "science": {"biology", "chemistry", "physics"}, } // Add a new subject classes["history"] = []string{"world", "european", "american"} // Append to an existing slice classes["math"] = append(classes["math"], "statistics") // Print all subjects for subject, topics := range classes { fmt.Printf("%s: %v\n", subject, topics) } }
The map stores slices as values. We demonstrate initialization, adding new keys, and appending to existing slices. This pattern is common for grouping data.
Map length and nil maps
This example covers map length and the difference between nil and empty maps. Understanding this is crucial for proper map usage.
package main import "fmt" func main() { // Nil map (cannot be used directly) var nilMap map[string]int fmt.Println("Nil map:", nilMap) // Empty initialized map emptyMap := make(map[string]int) fmt.Println("Empty map:", emptyMap) // Check length populatedMap := map[string]int{"a": 1, "b": 2} fmt.Println("Map length:", len(populatedMap)) // Initialize nil map before use nilMap = make(map[string]int) nilMap["now"] = 1 fmt.Println("Initialized nil map:", nilMap) }
Nil maps cannot store values until initialized. The len function returns the number of key-value pairs. Always initialize maps before use.
Map as function parameter
Maps are reference types in Go. This example shows how maps behave when passed to functions.
package main import "fmt" func updateMap(m map[string]int, key string, value int) { m[key] = value } func main() { scores := map[string]int{ "Alice": 90, "Bob": 85, } fmt.Println("Before update:", scores) updateMap(scores, "Alice", 95) updateMap(scores, "Carol", 88) fmt.Println("After update:", scores) }
Maps are passed by reference, so modifications inside functions affect the original map. No pointer is needed to modify the map contents.
Concurrent map access
This example demonstrates the need for synchronization when accessing maps from multiple goroutines.
package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup var mu sync.Mutex sharedMap := make(map[int]int) // Write to map from multiple goroutines for i := 0; i < 10; i++ { wg.Add(1) go func(n int) { defer wg.Done() mu.Lock() sharedMap[n] = n * n mu.Unlock() }(i) } wg.Wait() // Read from map mu.Lock() for k, v := range sharedMap { fmt.Printf("%d: %d\n", k, v) } mu.Unlock() }
Maps are not thread-safe. Concurrent access requires synchronization with mutexes. This example uses sync.Mutex to protect map operations.
Source
This tutorial covered the map
keyword in Go with practical
examples of map operations in various scenarios.
Author
List all Golang tutorials.