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

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

為什么golang slice 內部是這樣設計的?

為什么golang slice 內部是這樣設計的?

Go
慕桂英546537 2021-09-10 18:04:27
代碼:func main() {    a := []int{1, 2}    printSlice("a", a)    b := a[0:1]    printSlice("b origin", b)    b = append(b, 9)    printSlice("b after append b without growing capacity", b)    printSlice("a after append b without growing capacity", a)    b = append(b, 5, 7, 8)    printSlice("a after append b with grown capacity", a)    printSlice("b after append b with grown capacity", b)    b[0] = 1000    printSlice("b", b)    printSlice("a", a)      }func printSlice(s string, x []int) {    fmt.Printf("%s len=%d cap=%d %v\n",        s, len(x), cap(x), x)}輸出:a len=2 cap=2 [1 2]b origin len=1 cap=2 [1]b after append b without growing capacity len=2 cap=2 [1 9]a after append b without growing capacity len=2 cap=2 [1 9]a after append b with grown capacity len=2 cap=2 [1 9]b after append b with grown capacity len=5 cap=6 [1 9 5 7 8]b len=5 cap=6 [1000 9 5 7 8]a len=2 cap=2 [1 9]有趣的是在最后兩行印刷。我已經知道切片只是底層數組的一個窗口。當在容量內重新切片時,兩個切片共享相同的底層數組,但是當我重新切片以超過其容量時,兩個切片具有不同的底層數組。但是為什么golang的設計者選擇不將原始切片的底層數組改成新切片的底層數組,從而讓兩個切片仍然擁有相同的底層數組呢?在當前狀態下,當我更改新重新切片的某些元素的值時,我必須檢查是否更改了底層數組以決定此操作是否對它支持的其他切片有副作用(請參閱輸出的最后兩行)。我覺得這很尷尬。
查看完整描述

1 回答

?
慕桂英4014372

TA貢獻1871條經驗 獲得超13個贊

但是為什么golang的設計者選擇不將原始切片的底層數組改成新切片的底層數組,從而讓兩個切片仍然擁有相同的底層數組呢?

主要是,同一個數組的切片可以出現在程序中的任何地方——完全不同的函數、包等等。考慮到切片在內存中的布局方式,Go 必須“找到”共享數組的所有切片來更新它們;它沒有辦法。

其他一些數組列表實現(如 Python 列表)的方法是,您傳遞的實際上是一個指向Go 切片之類的指針,如果兩個變量保存“相同的列表”,則使用一個變量的附加也將顯示當你看著另一個的時候。這也有一些效率成本——另一個指針查找要做a[0]。在那些你真的需要一個附加在這里作為附加在那里的情況下,你可以使用指向切片的指針。

如果需要,指向切片的指針會為您提供別名,但不提供子切片 - 要獲得您要求的所有內容,您需要一種不同的安排,我無法想到野外的示例(偏移量,長度, 和指向struct { capacity int; firstElem *type }) 的指針。


查看完整回答
反對 回復 2021-09-10
  • 1 回答
  • 0 關注
  • 173 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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