Question
In Go, is there a way to get all the keys from a map?
I know len() gives the number of elements, but if I have a map like this:
m := map[string]string{
"key1": "val1",
"key2": "val2",
}
How can I iterate over all the keys in the map?
Short Answer
By the end of this page, you will understand how to loop through the keys of a Go map using range, how to collect keys into a slice when needed, why map order is not guaranteed, and how this pattern is used in real Go programs.
Concept
In Go, a map stores key-value pairs. When you want to visit every entry in a map, the usual tool is a for loop with range.
A Go map does not provide a separate built-in "get all keys" function. Instead, you iterate through the map directly:
for key := range m {
fmt.Println(key)
}
This works because range can loop over maps and return each key one at a time.
If you also need the value, you can write:
for key, value := range m {
fmt.Println(key, value)
}
This concept matters because maps are used everywhere in Go:
- configuration lookups
- counting frequencies
- caching data
- grouping records
- tracking flags or states
Understanding how to iterate over a map is essential for reading, transforming, validating, and exporting data.
One important rule: map iteration order in Go is not guaranteed. If you print keys from a map, they may appear in a different order between runs. If you need a stable order, collect the keys into a slice and sort them.
Mental Model
Think of a Go map like a labeled storage cabinet.
- The key is the label on a drawer.
- The value is what is stored inside that drawer.
len(m)tells you how many drawers exist.rangelets you walk past every drawer and read its label.
If you only care about the labels, you read just the keys. If you care about both the labels and contents, you read both key and value.
The cabinet does not promise that the drawers will appear in alphabetical or insertion order. You are simply visiting all existing drawers in an unspecified order.
Syntax and Examples
Basic syntax
To iterate over all keys in a Go map:
for key := range m {
fmt.Println(key)
}
To iterate over keys and values:
for key, value := range m {
fmt.Println(key, value)
}
Example: print all keys
package main
import "fmt"
func main() {
m := map[string]string{
"key1": "val1",
"key2": "val2",
"key3": "val3",
}
for key := range m {
fmt.Println(key)
}
}
This loops through the map and prints each key.
Example: collect keys into a slice
Sometimes you want a list of keys instead of printing them immediately.
package main
import "fmt"
func main() {
m := map[string]string{
"key1": "val1",
"key2": "val2",
"key3": "val3",
}
keys := make([]string, 0, len(m))
for key := range m {
keys = append(keys, key)
}
fmt.Println(keys)
}
This creates a slice and appends every key from the map.
Example: sorted keys
If you want predictable output order:
package main
import (
"fmt"
"sort"
)
func main() {
m := map[string]string{
"key2": "val2",
"key1": "val1",
"key3": "val3",
}
keys := make([]string, 0, len(m))
for key := range m {
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
fmt.Println(key, m[key])
}
}
This is the common pattern when order matters.
Step by Step Execution
Consider this example:
package main
import "fmt"
func main() {
m := map[string]string{
"name": "Ada",
"city": "London",
}
for key := range m {
fmt.Println("key:", key)
}
}
Step by step:
-
A map named
mis created. -
It contains two entries:
"name" -> "Ada""city" -> "London"
-
The loop starts:
for key := range m { -
range masks Go to visit every entry in the map. -
On each iteration, Go places the current key into the variable
key. -
fmt.Println("key:", key)prints that key. -
The loop continues until every map entry has been visited.
Possible output:
key: name
key: city
Or:
key: city
key: name
Both are correct, because map iteration order is not guaranteed.
If you wanted both key and value, the loop would be:
for key, value := range m {
fmt.Println(key, value)
}
Then each iteration gives you two pieces of data instead of one.
Real World Use Cases
Here are common situations where iterating over map keys is useful:
Configuration processing
config := map[string]string{
"host": "localhost",
"port": "8080",
}
for key := range config {
fmt.Println("config key:", key)
}
You may want to validate required settings or print supported options.
Counting and reporting
wordCount := map[string]int{
"go": 3,
"map": 2,
}
for word := range wordCount {
fmt.Println(word)
}
This is useful when generating summaries from counted data.
Building API responses
A service might store fields in a map and iterate over keys to produce output or check allowed fields.
Data validation
You can loop over submitted keys to reject unknown fields:
allowed := map[string]bool{
"name": true,
"email": true,
}
submitted := map[string]string{
"name": "Sam",
"role": "admin",
}
for key := range submitted {
if !allowed[key] {
fmt.Println("unexpected field:", key)
}
}
Logging and debugging
Developers often inspect maps by iterating over keys and values during debugging or diagnostics.
Real Codebase Usage
In real Go codebases, developers usually use map iteration in a few standard patterns.
1. Simple traversal
When order does not matter:
for key, value := range m {
process(key, value)
}
This is the most common pattern.
2. Collect then sort
When output must be deterministic, such as in tests, logs, or generated files:
keys := make([]string, 0, len(m))
for key := range m {
keys = append(keys, key)
}
sort.Strings(keys)
Then iterate over keys.
3. Validation against known keys
Maps are often used as sets:
allowed := map[string]struct{}{
"name": {},
"email": {},
}
for key := range input {
if _, ok := allowed[key]; !ok {
return fmt.Errorf("unknown field: %s", key)
}
}
This is common in request validation and config parsing.
4. Guard clauses during iteration
Developers often skip invalid entries early:
for key, value := range m {
if value == "" {
continue
}
fmt.Println(key, value)
}
5. Building derived data
A map may be turned into another structure:
keys := make([]string, 0, len(m))
for key := range m {
keys = append(keys, key)
}
This is useful for serialization, sorting, filtering, or UI output.
Common Mistakes
Assuming the order is fixed
Broken expectation:
for key := range m {
fmt.Println(key)
}
A beginner may expect insertion order or alphabetical order. Go does not guarantee either.
How to avoid it:
- collect keys into a slice
- sort the slice
- iterate over the sorted slice
Thinking len(m) gives access to keys
len(m) only tells you how many entries are in the map. It does not provide the keys themselves.
count := len(m)
fmt.Println(count)
This is useful for size, not traversal.
Ignoring the value when you actually need it
If you need both key and value, do not do an extra lookup unless necessary.
Less efficient style:
for key := range m {
fmt.Println(key, m[key])
}
Better:
for key, value := range m {
fmt.Println(key, value)
}
Trying to use a nonexistent keys() function
Go maps do not have a built-in keys() method.
Broken code:
keys := m.keys()
Correct approach:
keys := make([]string, 0, len(m))
for key := range m {
keys = append(keys, key)
}
Forgetting that map keys must match the map type
If your map is map[string]string, then keys are strings.
Broken code:
m := map[string]string{"a": "1"}
for key := range m {
var n int = key
fmt.Println(n)
}
This fails because key is a string, not an int.
Modifying logic based on iteration order
Do not write code that depends on the first key being a particular key. That is unreliable unless you sort keys first.
Comparisons
| Concept | What it does | When to use it |
|---|---|---|
len(m) | Returns the number of entries in the map | When you only need the size |
for key := range m | Iterates over keys only | When you only need keys |
for key, value := range m | Iterates over keys and values | When you need both |
| Collect keys into a slice | Builds a reusable list of keys | When you need to pass keys around |
| Sort collected keys | Produces deterministic order | When order matters |
range over map vs range over slice
| Structure | Order guaranteed? | Returned values |
|---|---|---|
| Map | No | Key, value |
| Slice | Yes, by index order | Index, value |
Keys only vs keys and values
for key := range m {
fmt.Println(key)
}
Use this when you only care about keys.
for key, value := range m {
fmt.Println(key, value)
}
Use this when you need both and want cleaner code.
Cheat Sheet
// Iterate over keys only
for key := range m {
fmt.Println(key)
}
// Iterate over keys and values
for key, value := range m {
fmt.Println(key, value)
}
// Get number of entries
n := len(m)
// Collect keys into a slice
keys := make([]string, 0, len(m))
for key := range m {
keys = append(keys, key)
}
Rules to remember
- Go maps are iterated with
for ... range. len(m)gives the count, not the keys.- Map iteration order is not guaranteed.
- If order matters, collect keys and sort them.
- Use
for key, value := range mwhen you need both pieces of data.
Common pattern for sorted output
keys := make([]string, 0, len(m))
for key := range m {
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
fmt.Println(key, m[key])
}
FAQ
How do I loop through all keys in a Go map?
Use for key := range m {}.
Can I get all map keys as a slice in Go?
Yes. Create a slice, then append each key while ranging over the map.
Does Go preserve map insertion order?
No. Map iteration order is not guaranteed.
How do I print both keys and values from a Go map?
Use for key, value := range m {}.
Is there a built-in function to return map keys in Go?
No built-in map method returns all keys directly. You iterate with range.
Why is my map output order changing?
Because Go maps do not guarantee iteration order. Sort the keys if you need stable output.
Mini Project
Description
Build a small Go program that stores environment settings in a map, prints all available setting names, and then prints them again in sorted order. This demonstrates basic map key iteration and the common real-world need for deterministic output.
Goal
Create a program that iterates over all keys in a map and also produces a sorted list of those keys.
Requirements
- Create a
map[string]stringwith at least four configuration entries. - Print all keys using a
for ... rangeloop. - Collect the keys into a slice.
- Sort the slice alphabetically.
- Print each sorted key together with its value.
Keep learning
Related questions
Are Go Maps Passed by Value or Reference?
Learn Go map parameter and return semantics: maps are passed by value, while copies share underlying data. Know when map pointers are useful.
Authentication for Go REST APIs: Sessions, Tokens, and Middleware
Learn practical authentication patterns for Go REST APIs, including password hashing, server sessions, bearer tokens, middleware, and security rules.
Automatic Build Versioning in Go: Embed Incrementing Build Numbers
Learn how to add automatic build versioning in Go using linker flags, build metadata, CI counters, and Git-based version values.