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"
{
m := []{
: ,
: ,
: ,
}
keys := ([], , (m))
key := m {
keys = (keys, key)
}
fmt.Println(keys)
}
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.
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": ,
: ,
}
submitted := []{
: ,
: ,
}
key := submitted {
!allowed[key] {
fmt.Println(, key)
}
}
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.
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 method.
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 |
|---|
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
Blank Identifier Imports in Go: What `_` Means in an Import Statement
Learn what `_` means in a Go import, why blank identifier imports run package init code, and when to use them safely.
Check if a Value Exists in a Slice in Go
Learn how to check whether a value exists in a slice in Go, and why Go has no Python-style `in` operator for arrays or slices.
Concatenating Slices in Go with append
Learn how to concatenate two slices in Go using append and the ... operator, with examples, pitfalls, and practical usage.