亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

附加到其他切片內的結構上的切片不持久

附加到其他切片內的結構上的切片不持久

Go
小唯快跑啊 2023-04-24 16:13:56
例如: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)  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 中獲得預期結果?
查看完整描述

2 回答

?
翻翻過去那場雪

TA貢獻2065條經驗 獲得超14個贊

在 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 slice

Test在制作 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) // 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上的工作代碼



查看完整回答
反對 回復 2023-04-24
?
BIG陽

TA貢獻1859條經驗 獲得超6個贊

這是由事實引起的,即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

這表明這是真的


查看完整回答
反對 回復 2023-04-24
  • 2 回答
  • 0 關注
  • 161 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號