ZetCode

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.

basic_map.go
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.

key_check.go
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.

map_iteration.go
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.

map_of_slices.go
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.

map_length.go
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.

map_function.go
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.

concurrent_map.go
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

Go language specification

This tutorial covered the map keyword in Go with practical examples of map operations in various scenarios.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Golang tutorials.