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

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

go slice 的行為不符合預期

go slice 的行為不符合預期

Go
藍山帝景 2023-08-14 14:31:22
我試圖親自動手切片,但我發現它的行為不符合預期。我試圖獲得 n 個不同大小的數組的笛卡爾積。輸出不正確。這是我的代碼func main() {   sl1 := []int{1,2,3}   sl2 := []int{4}   sl3 := []int{5,6}   sl4 := []int{8,9}   sl := [][]int{sl1,sl2,sl3,sl4}   res := cartesianMain(sl)   fmt.Println(res)}func cartesianMain(a [][]int)  [][]int {   res := [][]int{}   for i:=0;i<len(a[0]) ;i++{       res = append(res,[]int{a[0][i]})   }   for i:= 1;i<len(a) ;i++{       res = cartesianProduct(res,a[i])   }   return res;}func cartesianProduct(a [][]int, b []int) [][]int {   result := [][]int{}   for _,v1 := range b {       for _,v2 := range a {           result = append(result, append(v2,v1))       }   }return result}實際輸出:[[1 4 5 9] [2 4 5 9] [3 4 5 9] [1 4 6 9] [2 4 6 9] [3 4 6 9] [1 4 5 9] [2 4 5 9] [3 4 5 9] [1 4 6 9] [2 4 6 9] [3 4 6 9]]預期輸出:如果您看到 sl4 的第一個元素 8 被 9 覆蓋。正確答案是:[[1 4 5 8] [2 4 5 8] [3 4 5 8] [1 4 6 8] [2 4 6 8] [3 4 6 8] [1 4 5 9] [2 4 5 9] [3 4 5 9] [1 4 6 9] [2 4 6 9] [3 4 6 9]]
查看完整描述

1 回答

?
幕布斯7119047

TA貢獻1794條經驗 獲得超8個贊

這是因為append工作原理。在 Go 中,slice 是一個包含 3 個屬性的標頭:Len、Cap、 和Ptr。Len是切片本身的長度,Cap是切片底層數組(內存)的容量,Ptr是指向數組的指針。

append追加到基礎數組中沒有更多空間的切片時,它會分配一個比所需空間多的新基礎數組,并將原始切片的內容復制到其中,然后添加新元素。

append附加到切片時,其中Cap>?Len,即已分配的內存中仍然有足夠的空間,append保留底層數組并復制要添加到的元素a[Len+1](其中 a 是底層數組)。當兩個或多個切片共享底層內存時,這將導致問題。

經驗法則是經常檢查復制切片的需要,以避免不必要的底層數組共享。

要解決該問題,請更改result = append(result, append(v2,v1))result = append(result, append([]int{}, append(v2, v1)...)).

注1:是和append([]int{},append(v2,v1...))的快捷方式。

注2:在Go中,nil是slice的有效值。cartesianMain所以你可以通過設置來res擺脫split in 的分離[]int{nil}

注 3:為了獲得更好的性能和更少的分配,最好為已知切片設置容量(或長度)。在 中cartesianProduct,您可以使用result := make([][]int, 0, len(a)*len(b)).

游樂場:https://play.golang.org/p/rLqDGWoTLKS


查看完整回答
反對 回復 2023-08-14
  • 1 回答
  • 0 關注
  • 148 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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