附加到其他切片内的结构上的切片不持久

例如:


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]

}

我正在寻求帮助来理解打印语句 #3 和 #4。在#3 中我期待[apple bannana],在#4 中我期待[apple bannana carrot]。


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


initial所以,我的问题是:当它被插入到一个使它不起作用的切片中时会发生什么?此外,如何编写此代码才能在 print 语句 #4 中获得预期结果?


小唯快跑啊
浏览 130回答 2
2回答

翻翻过去那场雪

在 Golang 中提到:映射和切片值的行为类似于指针:它们是包含指向底层映射或切片数据的指针的描述符。复制映射或切片值不会复制它指向的数据。您附加到切片的方式s是通过将 Test 结构的副本添加到切片来创建一个新切片s。因此,您没有设置指向原始Test结构的指针。因此,如果结构内部的数据发生变化,它也会反映在切片中。这就是你面临的问题。  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 sliceTest在制作 slice 时创建一个指向结构的指针s,每当您更改原始结构中的元素时,它都会反映更改。例如:package mainimport "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]Go Playground上的工作代码

BIG阳

这是由事实引起的,即initial变量与s[0]- 它们是两个自Test变量并且附加到一个不会改变第二个。initial传递给时按值复制到不同的对象append()证明:fmt.Printf("second: %p, initial: %p\n", &second.elems[0], &initial.elems[0])(其中second.elems[0] == "apple"和initial.elems[0] == "apple")输出second: 0xc00000a120, initial: 0xc00000a0c0这表明这是真的
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go