1

I have the following code which causes a weird result. I cannot understand why:

func main() {
    var s = []int{2, 3}
    var s1 = append(s, 4)
    var a = append(s1, 5)
    var b = append(s1, 6)
    fmt.Println(s)
    fmt.Println(s1)
    fmt.Println(a)
    fmt.Println(b)
}

This then results in:

[2 3]
[2 3 4]
[2 3 4 6]
[2 3 4 6]

My question is: why a is not [2 3 4 5] but [2 3 4 6]? I know append to b changes a, but how. Is this a bug because I never changed a directly and obviously I don't want this happen?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
lty
  • 108
  • 1
  • 6
  • 4
    [This](https://blog.golang.org/go-slices-usage-and-internals) and [this](https://blog.golang.org/slices) should be very helpful. – chrk Dec 01 '18 at 16:20
  • 3
    See explanation in [this asnwer](https://stackoverflow.com/questions/16248241/concatenate-two-slices-in-go/40036950#40036950). – icza Dec 01 '18 at 16:32
  • 1
    after messing about with this and reading all the docs referenced above I think I vaguely get it now. The slice the append returns is somewhat like a pointer that references the memory that s1 holds. – Vorsprung Dec 01 '18 at 21:12
  • @Vorsprung That's about right. But I wouldn't say it is memory that "`s1` holds" . `s1`, `a` and `b` are slices that all reference the same underlying array. The memory is not "held" by one of the slices. – Chris Drew Dec 01 '18 at 22:12

1 Answers1

1

Keep in mind that a slice is a structure of 3 fields.

  • a pointer to the underlying array
  • length of the slice
  • capacity of the slice

append() function may either modify its argument in-place or return a copy of its argument with an additional entry, depending on the size and capacity of its input. append() function creates a new slice, if the length the slice is greater than the length of the array pointed by the slice.

Ehsan.Saradar
  • 664
  • 6
  • 10