A range loop visits each item in a collection without manually checking its length. Use it when code should work for any number of items, including an empty slice: the loop simply runs zero times. section 4.2.8 section 2.9
For an array or slice, `for i := range items` supplies indices. `for i, item := range items` supplies each index and a copy of its value. Write `for _, item := range items` when the index is unnecessary. section 4.1.4 section 2.9
Listing 2.47 The two different range loop forms for slices
stringList := []string{"A", "B", "C"}
// Single-value form gets just the index.
for index := range stringList {
fmt.Println(index)
}
// Output:
// 0
// 1
// 2
// Two-value form gets the index and a copy of the value.
for index, value := range stringList {
fmt.Println(index, value)
}
// Output:
// 0 A
// 1 B
// 2 C
// Discarding the index.
for _, value := range stringList {
fmt.Println(value)
}
// Output:
// A
// B
// C
Compare the one-value, two-value, and discarded-index forms on the same slice. section 2.9
Process every filename
`for _, filename := range os.Args[1:]` visits command-line filenames while skipping the program name. If opening one file fails, log the error and `continue` so the remaining files can still be processed. section 2.9
A ranged value is a copy. Changing that variable does not change an array element; use the supplied index to assign to the element instead. If processing requires reverse order or skipping items, an index-controlled `for` loop is a better fit. section 4.1.4
Listing 4.59 Using a range statement Instead of explicit indices
func printMedalists3(raceName string, contestants []string) {
fmt.Printf("Results for %s:\n", raceName)
for place, contestant := range contestants {
switch place {
case 0:
fmt.Printf("Gold Medal: %s\n", contestant)
case 1:
fmt.Printf("Silver Medal: %s\n", contestant)
case 2:
fmt.Printf("Bronze Medal: %s\n", contestant)
default:
fmt.Printf("Finisher: %s\n", contestant)
// or just return
}
}
}
func main() {
race1 := []string{"Sally", "Steve", "Jo", "Adam"}
race2 := []string{"Jon", "Jen"}
race3 := []string{}
printMedalists3("Race 1", race1)
// Race 2 only has two contestants, but we still need to list them!
printMedalists3("Race 2", race2)
// Throw in a race with no contestants at all.
printMedalists3("Race 3", race3)
}
A results function uses the range index to label finishers without assuming the slice contains at least three people. section 4.2.8
Range has collection-specific details. Over a string, it supplies each character as a rune and the byte index where that character starts. Over a map, it supplies a key and optionally a copy of its value; map iteration order is unspecified. Deleting selected entries while ranging over a map is safe if the map is not being accessed elsewhere at the same time. Range also works with channels. section 3.8.5 section 4.3.5 section 2.9


