← Back to Go Course | Chapter 3: Control Flow | Lesson 7 of 7

The range Keyword

range is Go's way of saying 'go through every item in this collection, one by one, and tell me where each one is'.

Ranging Over a Slice

range on a slice or array gives you both the index and the value at each step, letting you avoid manually managing an index variable and bounds checks.

Example: Ranging Over a Slice

markup
package main

import "fmt"

func main() {
	fruits := []string{"apple", "banana", "cherry"}
	for i, fruit := range fruits {
		fmt.Println(i, fruit)
	}
}

Ignoring the Index or Value

If you only care about the value and not the index (or vice versa), the blank identifier _ discards the part you don't need, satisfying Go's rule that every declared variable must be used.

Note: Go's compiler rejects a declared-but-unused variable, so _ is essential when you only need one of the two range values.

Example: Ignoring the Index or Value

markup
package main

import "fmt"

func main() {
	fruits := []string{"apple", "banana", "cherry"}
	for _, fruit := range fruits {
		fmt.Println("fruit:", fruit)
	}
}

Ranging Over a Map

range on a map yields each key-value pair, but the order of iteration is deliberately randomized by the Go runtime every time the program runs, which prevents code from accidentally depending on a specific order.

Note: Map iteration order is intentionally randomized by Go each run -- never rely on it being consistent.

Example: Ranging Over a Map

markup
package main

import "fmt"

func main() {
	ages := map[string]int{"Amit": 30, "Sara": 25}
	total := 0
	for _, age := range ages {
		total += age
	}
	fmt.Println("total age:", total)
}

Ranging Over a String

range on a string decodes it as UTF-8, yielding the byte index and the rune (full character) at that position -- correctly handling multi-byte characters, unlike a plain byte-index loop.

Example: Ranging Over a String

markup
package main

import "fmt"

func main() {
	for i, r := range "Go!" {
		fmt.Printf("%d: %c\n", i, r)
	}
}
Common Mistakes
  1. Assuming the range loop variable is a fresh variable each iteration in older Go versions -- pre-1.22 it was reused, causing common closure-capture bugs.
  2. Ignoring the index/key that range provides when only the value is needed, instead of using the blank identifier _ to discard it.
  3. Modifying a slice's length while ranging over it, which does not change how many iterations the already-started range performs.
Chapter Summary
  • range iterates over arrays, slices, strings, maps, and channels, adapting its output to each type.
  • For slices/arrays, range yields index and value; for maps, key and value; for strings, byte index and rune.
  • Use the blank identifier _ to ignore a value you don't need from range.
  • Since Go 1.22, each range iteration gets its own fresh loop variable, avoiding an old class of closure bugs.
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.