Slices are passed by value, but the value is a reference:
func modify(s []int) {
s[0] = 100 // Modifies original
}
nums := []int{1, 2, 3}
modify(nums)
fmt.Println(nums[0]) // 100
The slice header is copied, but it points to the same array. Functions can modify the underlying data.