skip to content
Alvin Lucillo

For range value and pointer semantics

/ 2 min read

💻 Tech

Using either the two forms of for…range below can make a difference of whether you’ll modify the original data or not.

In the first form, since it’s using value semantics, changing the contents of animais will not interrupt the for loop. This is because the semantic version creates a copy of the slice to operate on, so upon entering the loop, it knows the length and the items to work with. The scope of the loop only operates on the copy of the slice. Outside it, that’s you’ll see that the 5 elements become 3 elements, but it didn’t affect the loop.

In contrast, the second form produced a runtime error because it uses the pointer semantics form; that is, the loop operates under the original slice and iterates to the length of the slice, but since the scope of the loop can mutate the slice, the original slice was modified, and accessing the 4th element caused the panic.

	// Value semantics
	animais := []string{"Gato", "Cao", "Cavalo", "Macaco", "Passaro"}
	for _, animal := range animais {
		animais = animais[:3]
		fmt.Printf("v[%s]\n", animal)
	}
	fmt.Println(animais)

	fmt.Println()

	// Pointer semantics
	animais = []string{"Gato", "Cao", "Cavalo", "Macaco", "Passaro"}
	for i := range animais {
		animais = animais[:3]
		fmt.Printf("p[%s]\n", animais[i])
	}

Output:

v[Gato]
v[Cao]
v[Cavalo]
v[Macaco]
v[Passaro]
[Gato Cao Cavalo]

p[Gato]
p[Cao]
p[Cavalo]

panic: runtime error: index out of range [3] with length 3