golang切片使用append追加內容導致切片值異常問題


在一次對切片合並處理后,原本是希望在得到一個新的切片同時不改變原切片,以前做過類似的處理,是沒有問題的,但是這次發現原切片的值也被改變了,

示例代碼:

s1 := []int{1, 2, 3, 4}
s2 := []int{-1, -2, -3}

s3 := append(s1[:1], s2...)

fmt.Println(s3)
fmt.Println(s1)

  

 

打印結果:

[1 -1 -2 -3] [1 -1 -2 -3]

 

之前處理過類似情況,s1的值並沒有被改變,但是這次卻改變了。

 

原因分析


根據上面描述,基本可以判斷出是append的錯誤應用造成的,因此重新對對append的用法進行學習,經過查閱相關資料,確定了append有以下兩個原則:

(1)append函數調用后,應該使用返回值作為結果。

(2)append函數調用后,不應該再使用實參傳入的slice。
所以使用append函數一般都是s = append(s,elem1)這種用法,也就是把結果重新賦值給原來的slice。

 

官方解釋:

slice的底層存儲依賴於底層數組(underlying array)。

 

例子中,s1初始化的值是[]int{1, 2, 3, 4},它的len和cap都是4,所以它的底層數組是一個長度為4的數組[4]int{1,2,3,4}
基於slice的特點,s1[:1]和s1是共享底層數組的,所以s1[:1]這個slice的改變是會影響到underlying array的。

 

而之所以以前可以得到一個新的切片s3且不改變s1,是因為:

新切片的容量不能容納所有追加元素,append會申請一個新的底層數組用來存儲,也會返回一個新的slice,這不會影響到原本的底層數組,也就不會影響到原本的slice。

 

解決方案


不應該將append的返回值賦給新變量,而應該重新賦值給要追加元素的切片

上面示例修改為:

s1 := []int{1, 2, 3, 4}
s2 := []int{-1, -2, -3}

s1 := append(s1[:1], s2...)

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM