追加在不存在的其他切片内部的结构上切片

For example:

package main

import "fmt"

type Test struct {
  elems []string
}

func main() {
  initial := Test{
    elems: make([]string, 0),
  }
  initial.elems = append(initial.elems, "apple")
  fmt.Println(initial.elems) // #1 [apple]

  s := make([]Test, 0)
  s = append(s, initial)

  initial.elems = append(initial.elems, "bannana")
  fmt.Println(initial.elems) // #2 [apple bannana]
  fmt.Println(s[0].elems) // #3 [apple]

  second := s[0]
  second.elems = append(second.elems, "carrot")
  fmt.Println(second.elems) // #4 [apple bannana]
}

I am looking for help understanding print statements #3 and #4. In #3 I expect [apple bannana] and in #4 I am expecing [apple bannana carrot].

It is my understanding that the elems field which is a slice is automatically passed by reference and therefore each append that I do in the above block of code should modify the underlying array. But, apparently that is not the case.

So, my question is: What happens to initial when it gets inserted into a slice that makes this not work? Also, how would one write this code to get the expected result at print statement #4?

In Golang it is mentioned:

Map and slice values behave like pointers: they are descriptors that contain pointers to the underlying map or slice data. Copying a map or slice value doesn't copy the data it points to.

The way you are appending to the slice s is creating a new slice by adding the copy of Test struct to the s slice. Hence you are not setting a pointer to the original Test struct. So that if data changes inside the struct it will be reflected in the slice too. This is the problem you are facing.

  initial.elems = append(initial.elems, "apple")
  fmt.Println(initial.elems) // #1 [apple]

  s := make([]Test, 0) // this should be pointer to the struct to have teh changes in future to original struct.
  s = append(s, initial) // appending to the s slice

Create a pointer to the Test struct when making slice s, which will reflect the change whenever you change the elems inside original struct. For example:

package main
import "fmt"

type Test struct {
  elems []string
}

func main() {
  initial := Test{
    elems: make([]string, 0),
  }
  initial.elems = append(initial.elems, "apple")
  fmt.Println(initial.elems) // #1 [apple]

  s := make([]*Test, 0) // create a pointer to Test struct.
  s = append(s, &initial)

  initial.elems = append(initial.elems, "bannana")
  fmt.Println(initial.elems) // #2 [apple bannana]
  fmt.Printf("%+v
",*s[0]) // #3 [apple banana]

  second := s[0]
  second.elems = append(second.elems, "carrot")
  fmt.Println(second.elems) // #4 [apple bannana carrot]
}

Output:-

[apple]
[apple bannana]
{elems:[apple bannana]}
[apple bannana carrot]

Working Code on Go Playground

Its caused by fact, that the initial variable isn't the same as s[0] - they are two independent Test variables and appending to one doesn't change the second. initial is being copied by value to different object when passed to append()

Proof:

fmt.Printf("second: %p, initial: %p ", &second.elems[0], &initial.elems[0])

(where second.elems[0] == "apple" and initial.elems[0] == "apple") outputs

second: 0xc00000a120, initial: 0xc00000a0c0

which shows, that this is true