Go Map and Key-Value Storage

A map in Go stores a collection of key-value pairs. Each key in a map is unique, while multiple keys may contain the same value. Maps are useful when a program needs to find, add, update, or remove a value by its key.

You access a map value by placing its key inside square brackets. A map key therefore serves a purpose similar to an array index, but it does not have to be an integer.

Go maps are reference-like data structures. Assigning one map variable to another does not create an independent copy of all entries; both variables refer to the same underlying map data.

Declare a Map in Go

To declare a map, use the map keyword followed by the key type inside square brackets and the value type after the brackets.

</>
Copy
var map_name map[key_data_type]value_data_type

The square brackets around the key type are mandatory. The key type must be comparable, which means values of that type can be compared using == and !=. Common key types include strings, integers, booleans, pointers, arrays, structs containing comparable fields, and interfaces containing comparable dynamic values. Slices, maps, and functions cannot be used directly as map keys.

example.go

</>
Copy
package main

import "fmt"

func main() {
    var colorMap map[string]string
    fmt.Println(colorMap)
}

Output

map[]

This declaration creates a nil map. A nil map has no entries, can be read safely, and has a length of zero. However, assigning a new key-value pair to a nil map causes a runtime panic. Initialize the map with make or a map literal before writing to it.

Initialize a Go Map with Values

A map literal initializes a map and can include its initial key-value pairs. Separate each key and value with a colon and separate entries with commas.

</>
Copy
var map_name = map[key_data_type]value_data_type {key1:value1, key2:value2}

The square brackets belong to the map type and are not optional. The key and value of every entry must be assignable to the declared key and value types.

example.go

</>
Copy
package main

import "fmt"

func main() {
    var colorMap = map[string]string {"white":"#FFFFFF", "black":"#000000", "red":"#FF0000", "blue":"#0000FF", "green":"#00FF00"}
    fmt.Println(colorMap)
}

Output

map[white:#FFFFFF black:#000000 red:#FF0000 blue:#0000FF green:#00FF00]

The displayed order is not guaranteed. A map should not be used when the program depends on entries remaining in insertion order.

Initialize an Empty Go Map with make

Use the built-in make function when you need an initialized map without supplying all entries in advance. After initialization, assign values using bracket notation.

example.go

</>
Copy
package main

import "fmt"

func main() {
	var colorMap = make(map[string]string)
	colorMap["white"] = "#FFFFFF"
	colorMap["black"] = "#000000"
	colorMap["red"] = "#FF0000"
	colorMap["blue"] = "#0000FF"
	colorMap["green"] = "#00FF00"
	
	fmt.Println(colorMap)
}

Output

map[green:#00FF00 white:#FFFFFF black:#000000 red:#FF0000 blue:#0000FF]

The key-value pairs may appear in a different order on another run. Map iteration and formatted map output must be treated as unordered.

The make function can also receive an optional initial capacity hint, such as make(map[string]string, 10). The hint may reduce allocation work when the approximate number of entries is known, but it does not set the map’s length or impose a maximum size.

Access a Value by Key in a Go Map

Place a key inside square brackets to retrieve its corresponding value. The result has the map’s declared value type.

example.go

</>
Copy
package main

import "fmt"

func main() {
	var colorMap = map[string]string {"white":"#FFFFFF", "black":"#000000", "red":"#FF0000", "blue":"#0000FF", "green":"#00FF00"}
	
	fmt.Println(colorMap["white"])
	fmt.Println(colorMap["red"])
}

Output

#FFFFFF
#FF0000

Check Whether a Go Map Key Exists

Reading a missing key does not cause an error. Go returns the zero value of the map’s value type. To distinguish a missing key from a stored zero value, use the two-result map lookup form, commonly called the comma-ok idiom.

</>
Copy
value, exists := mapName[key]

The Boolean result is true when the key exists and false when it does not.

</>
Copy
package main

import "fmt"

func main() {
    scores := map[string]int{
        "Alice": 0,
        "Bob":   18,
    }

    score, exists := scores["Alice"]
    fmt.Println(score, exists)

    score, exists = scores["Carol"]
    fmt.Println(score, exists)
}

Output

0 true
0 false

Both lookups return 0, but the exists value shows that only Alice is present in the map.

Get a Default Value from a Go Map

Go does not provide a separate built-in map function for returning a custom default. Check the Boolean result of a lookup and assign the required fallback value when the key is absent.

</>
Copy
package main

import "fmt"

func main() {
    settings := map[string]string{
        "theme": "dark",
    }

    language, exists := settings["language"]
    if !exists {
        language = "en"
    }

    fmt.Println(language)
}

Output

en

Iterate Over a Go Map with range

Use Range to iterate through the key-value pairs in a map.

example.go

</>
Copy
package main

import "fmt"

func main() {
	var colorMap = map[string]string {"white":"#FFFFFF", "black":"#000000", "red":"#FF0000", "blue":"#0000FF", "green":"#00FF00"}
	
	for key, value := range colorMap {
		fmt.Println("Hex value of", key, "is", value)
	}
}

Output

Hex value of white is #FFFFFF
Hex value of black is #000000
Hex value of red is #FF0000
Hex value of blue is #0000FF
Hex value of green is #00FF00

The iteration order is not specified and can differ from the output shown above. Code must not rely on one particular order.

Iterate Over Only Go Map Keys or Values

Omit the value variable when only keys are needed. Use the blank identifier for the key when only values are needed.

</>
Copy
package main

import "fmt"

func main() {
    colors := map[string]string{
        "red":   "#FF0000",
        "green": "#00FF00",
        "blue":  "#0000FF",
    }

    for key := range colors {
        fmt.Println("Key:", key)
    }

    for _, value := range colors {
        fmt.Println("Value:", value)
    }
}

Sort Go Map Keys for Predictable Output

When output must be consistent, copy the keys into a slice, sort the slice, and then access map values in the sorted-key order.

</>
Copy
package main

import (
    "fmt"
    "sort"
)

func main() {
    colors := map[string]string{
        "white": "#FFFFFF",
        "black": "#000000",
        "red":   "#FF0000",
    }

    keys := make([]string, 0, len(colors))
    for key := range colors {
        keys = append(keys, key)
    }

    sort.Strings(keys)

    for _, key := range keys {
        fmt.Println(key, colors[key])
    }
}

Output

black #000000
red #FF0000
white #FFFFFF

Update a Value for a Go Map Key

Update an existing value by assigning a new value to its key. The same syntax also inserts a new entry when the key is not already present.

example.go

</>
Copy
package main

import "fmt"

func main() {
	var colorMap = map[string]string {"white":"#FFFFFF", "black":"#000000", "red":"#FF0000"}
	
	// update
	colorMap["red"] = "#FF2222"
	
	fmt.Println(colorMap["red"])
}

Output

#FF2222

Delete a Key-Value Pair from a Go Map

Use the built-in delete function to remove the entry associated with a key.

</>
Copy
delete(map_name, Key)

Calling delete with a key that is not present has no effect and does not cause an error. Deleting from a nil map is also safe.

In the following example, the entries with the keys white and black are removed.

example.go

</>
Copy
package main

import "fmt"

func main() {
	var colorMap = map[string]string {"white":"#FFFFFF", "black":"#000000", "red":"#FF0000", "blue":"#0000FF", "green":"#00FF00"}
	
	delete(colorMap, "white")
	delete(colorMap, "black")
	
	fmt.Println(colorMap)
}

Output

map[blue:#0000FF green:#00FF00 red:#FF0000]

Find the Number of Entries in a Go Map

Pass a map to the built-in len function to get its current number of key-value pairs. The result is zero for both an initialized empty map and a nil map.

</>
Copy
package main

import "fmt"

func main() {
    colors := map[string]string{
        "red":   "#FF0000",
        "green": "#00FF00",
        "blue":  "#0000FF",
    }

    fmt.Println(len(colors))

    delete(colors, "green")
    fmt.Println(len(colors))
}

Output

3
2

Nil Maps and Empty Maps in Go

A nil map and an initialized empty map both have a length of zero, but they are not identical. A nil map has not been initialized and cannot accept assignments. An empty map created with make or a literal is ready to receive entries.

</>
Copy
package main

import "fmt"

func main() {
    var nilMap map[string]int
    emptyMap := make(map[string]int)

    fmt.Println(nilMap == nil)
    fmt.Println(emptyMap == nil)

    fmt.Println(nilMap["count"])
    emptyMap["count"] = 1
    fmt.Println(emptyMap["count"])
}

Output

true
false
0
1

A map can be compared directly only with nil. Two map values cannot be compared with each other using ==.

Copy a Go Map Without Sharing Entries

Assigning one map variable to another shares the same underlying map. To create an independent shallow copy, initialize a new map and copy each entry.

</>
Copy
package main

import "fmt"

func main() {
    original := map[string]int{
        "apples":  3,
        "oranges": 5,
    }

    copied := make(map[string]int, len(original))
    for key, value := range original {
        copied[key] = value
    }

    copied["apples"] = 10

    fmt.Println(original["apples"])
    fmt.Println(copied["apples"])
}

Output

3
10

This is a shallow copy. When map values contain slices, pointers, maps, or other reference-like data, those nested values may still share underlying data.

Concurrent Access to Go Maps

A regular Go map is not safe for unsynchronized concurrent reads and writes. When multiple goroutines may modify a map, protect access with synchronization such as sync.Mutex or sync.RWMutex, or use a design in which one goroutine owns the map. The sync.Map type is available for specialized concurrent access patterns, but it is not a general replacement for every typed map.

Frequently Asked Questions About Go Maps

How do I initialize a Go map with values?

Use a map literal such as map[string]int{"one": 1, "two": 2}. Use make(map[string]int) when the map should start empty and receive values later.

How do I check whether a key exists in a Go map?

Use the two-result lookup form: value, exists := myMap[key]. The exists result is true only when the key is present.

What does a Go map return for a missing key?

It returns the zero value of the map’s value type. For example, a missing key in a map[string]int returns 0, and a missing key in a map[string]string returns an empty string.

Can I depend on Go map iteration order?

No. Map iteration order is not specified. Sort the keys separately when output or processing must follow a predictable order.

Why does assignment to my Go map cause a panic?

The map may be nil. A declared but uninitialized map can be read, but it cannot accept assignments. Initialize it with make or a map literal before adding entries.

Go Map Tutorial Editorial QA Checklist

  • Confirm that map declaration examples distinguish a nil map from an initialized empty map.
  • Verify that every new Go code block uses the language-go PrismJS class and that result-only blocks use output.
  • Do not describe map iteration or printed map entries as having a guaranteed order.
  • Use the comma-ok lookup when an example must distinguish a missing key from a stored zero value.
  • Check that all map key types shown are comparable and that examples do not use slices, maps, or functions as keys.
  • State that assigning to a nil map panics while reads, len, and delete remain safe.
  • Ensure concurrent map-writing examples include appropriate synchronization guidance.

Conclusion

In this Go Tutorial, we learned how to declare and initialize Go maps, access values, check whether keys exist, supply default values, iterate over entries, sort map keys, update values, delete entries, count entries, copy maps, and handle nil and concurrent map access correctly.