Use range to visit every value in a slice.

range loop `range` gives an index and value for each element in a slice.

Range Loops

scores
range_loop.go
Replay: real traced execution (multi-file project)
package main

import "fmt"

func main() {
	var scores = []int{82, 91, 76}
	best := scores[0]

	for _, score := range scores {
		if score > best {
			best = score
		}
	}

	fmt.Println("scores=", scores)
	fmt.Println("best=", best)
}
package main

import "fmt"

func main() {
	var scores = []int{100, 95, 90}
	best := scores[0]

	for _, score := range scores {
		if score > best {
			best = score
		}
	}

	fmt.Println("scores=", scores)
	fmt.Println("best=", best)
}
package main

import "fmt"

func main() {
	var scores = []int{60, 70, 80}
	best := scores[0]

	for _, score := range scores {
		if score > best {
			best = score
		}
	}

	fmt.Println("scores=", scores)
	fmt.Println("best=", best)
}
  1. scores ← []int{82, 91, 76}, best ← 82

    5func main() {6  var scores→ []int{82, 91, 76} = []int{82, 91, 76} //@scores=[]int{100, 95, 90}, []int{60, 70, 80}7  best→ 82 := scores[0]82
  2. for _, score := range scores

    pass 1 of 3
    9for _, score82 := range scores[]int{82, 91, 76} {10  if score > best {
    All 3 passes — pass 1 is the card above
    passscorebest
    182
    29182 91
    376
  3. best ← 91

    9for _, score := range scores {10  if score91 > best82 {11    best→ 91 = score9112  }
  4. fmt.Println("scores=", scores)

    15  fmt.Println("scores=", scores[]int{82, 91, 76})16  fmt.Println("best=", best91)17}
    outputscores= [82 91 76]
    best= 91
  1. scores ← []int{100, 95, 90}, best ← 100

    5func main() {6  var scores→ []int{100, 95, 90} = []int{100, 95, 90}7  best→ 100 := scores[0]100
  2. for _, score := range scores

    pass 1 of 3
    9for _, score100 := range scores[]int{100, 95, 90} {10  if score > best {
    All 3 passes — pass 1 is the card above
    passscore
    1100
    295
    390
  3. fmt.Println("scores=", scores)

    15  fmt.Println("scores=", scores[]int{100, 95, 90})16  fmt.Println("best=", best100)17}
    outputscores= [100 95 90]
    best= 100
  1. scores ← []int{60, 70, 80}, best ← 60

    5func main() {6  var scores→ []int{60, 70, 80} = []int{60, 70, 80}7  best→ 60 := scores[0]60
  2. for _, score := range scores

    pass 1 of 3
    9for _, score60 := range scores[]int{60, 70, 80} {10  if score > best {
    All 3 passes — pass 1 is the card above
    passscorebest
    160
    27060 70
    38070 80
  3. best ← 70

    pass 1 of 2
    9for _, score := range scores {10  if score70 > best60 {11    best→ 70 = score7012  }
  4. best ← 80

    pass 2 of 2
    9for _, score := range scores {10  if score80 > best70 {11    best→ 80 = score8012  }
  5. fmt.Println("scores=", scores)

    15  fmt.Println("scores=", scores[]int{60, 70, 80})16  fmt.Println("best=", best80)17}
    outputscores= [60 70 80]
    best= 80

Follow the Range

  1. scores starts as [82 91 76].
  2. best tracks the largest score seen so far.
  3. The loop sees 82, then replaces it with 91.
  4. 76 is lower than 91, so best stays 91.
  5. The program prints scores= [82 91 76] and best= 91. | score visited | best after this value | | --- | --- | | 82 | 82 | | 91 | 91 | | 76 | 91 |

Exercise: range_loop.go

Reproduce best= 91, then use the pinned score variants to predict best= 100 and best= 80.