Lab on pass by reference for slices in Golang

The below snippets of code appeared in the lab on pointers.
image
again

main.go gives an output of
[10 20 30]
[5 15 25]

again.go gives an output of
[10 20 30]
[10 20 30]

Could someone explain to me the reason for the difference in output? I thought slices in golang are passed by reference and would therefore give the same output as that for main.go

Thanks!

Hi @nibblesmeow

In main.go this is happening. The key point is in the second paragraph where it says “In this case, no new slice is created”, so the arr slice is effectively passed by reference.

An unbounded slice like []int will always be a reference, since the compiler cannot know in advance how much stack to allocate for the function arguments.

In again.go the modify() function expects an explicit slice of exactly 3 integers, and so is passed by value as the compiler knows to reserve stack space for exactly 3 integers.

We can rewrite it like this, since we know the type is a [3]int and use pointers to achieve the same result as main.go

func main() {
	arr := [3]int{10, 20, 30}
	fmt.Println(arr)
	modify(&arr)
	fmt.Println(arr)
}

func modify(numbers *[3]int) {
	for i := range numbers {
		numbers[i] -= 5
	}
}
1 Like

Hi Alistair,

Thanks for your explanation. It makes sense now, since arrays are passed by value and slices passed by reference.