Pointers 在另一个切片内追加到结构上的切片,而不是持久化

Pointers 在另一个切片内追加到结构上的切片,而不是持久化,pointers,go,slice,Pointers,Go,Slice,例如: 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,

例如:

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]
}
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\n",*s[0]) // #3 [apple banana]

  second := s[0]
  second.elems = append(second.elems, "carrot")
  fmt.Println(second.elems) // #4 [apple bannana carrot]
}
我正在寻求帮助,了解打印语句3和4。在#3我期待着
[apple bannana]
,在#4我期待着
[apple bannana carrot]

我的理解是,
elems
字段是一个切片,它是通过引用自动传递的,因此我在上述代码块中所做的每个追加都应该修改底层数组。但是,显然情况并非如此


所以,我的问题是:
initial
当它被插入到一个切片中时,会发生什么情况,这使得它无法工作?此外,如何编写此代码以获得打印语句4的预期结果?

其原因是,
初始
变量与
s[0]
不同-它们是两个独立的
测试
变量,附加到一个变量后不会改变第二个变量<当传递到
append()

证明:

fmt.Printf(“秒:%p,首字母:%p\n”、&second.elems[0]、&initial.elems[0])

(其中
second.elems[0]==“apple”
initial.elems[0]==“apple”
) 输出

秒:0xc00000a120,首字母:0xc00000a0c0


这表明,这是正确的

在Golang中提到:

映射和切片值的行为类似于指针:它们是 包含指向基础映射或切片数据的指针。复制地图或 切片值不会复制它指向的数据

添加到切片
s
的方法是通过将Test struct的副本添加到
s
切片来创建一个新切片。因此,您没有设置指向原始
Test
struct的指针。因此,如果数据在结构内部发生更改,它也将反映在切片中。这就是你面临的问题

  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
在制作切片
s
时,创建指向
测试
结构的指针,每当您更改原始结构中的元素时,该指针都将反映更改。例如:

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]
}
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\n",*s[0]) // #3 [apple banana]

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

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

切片上的工作代码按值传递。切片值具有指向备份数组、长度和容量的指针。更改initial.elems中的切片值不会更改s[0]中的切片值。elems CTRL+F“附加到并复制切片”可以在切片中存储指针,也可以通过索引引用其内容。@tike s:=make([]*Test,0)//创建指向测试结构或测试结构指针切片的指针吗?