Go語言切片:子切片修改和append操作是如何影響原切片的?

Go語言切片:子切片修改和append操作是如何影響原切片的?

go語言切片:子切片修改與append操作的微妙關系

Go語言的切片(slice)是強大的動態數組,但其基于底層數組的特性,在子切片操作時容易產生誤解。本文將深入探討子切片修改和append操作對原切片的影響,并通過代碼示例進行分析。

讓我們觀察以下代碼:

s1 := []int{1, 2, 3, 4} s2 := s1[2:] fmt.Printf("s1: %v, len %d, cap: %d address: %p n", s1, len(s1), cap(s1), &s1) fmt.Printf("s2: %v, len %d, cap: %d address: %p n", s2, len(s2), cap(s2), &s2) //s1: [1 2 3 4], len 4, cap: 4 address: 0xc00000c108  (地址會因運行環境而異) //s2: [3 4], len 2, cap: 2 address: 0xc00000c120  (地址會因運行環境而異)  s2[0] = 99 fmt.Printf("s1: %v, len %d, cap: %d address: %p n", s1, len(s1), cap(s1), &s1) fmt.Printf("s2: %v, len %d, cap: %d address: %p n", s2, len(s2), cap(s2), &s2) //s1: [1 2 99 4], len 4, cap: 4 address: 0xc00000c108 (地址會因運行環境而異) //s2: [99 4], len 2, cap: 2 address: 0xc00000c120 (地址會因運行環境而異)  s2 = append(s2, 199) fmt.Printf("s1: %v, len %d, cap: %d address: %p n", s1, len(s1), cap(s1), &s1) fmt.Printf("s2: %v, len %d, cap: %d address: %p n", s2, len(s2), cap(s2), &s2) //s1: [1 2 99 4], len 4, cap: 4 address: 0xc00000c108 (地址會因運行環境而異) //s2: [99 4 199], len 3, cap: 4 address: 0xc00000c120 (地址會因運行環境而異)  s2[1] = 1999 fmt.Printf("s1: %v, len %d, cap: %d address: %p n", s1, len(s1), cap(s1), &s1) fmt.Printf("s2: %v, len %d, cap: %d address: %p n", s2, len(s2), cap(s2), &s2) //s1: [1 2 99 4], len 4, cap: 4 address: 0xc00000c108 (地址會因運行環境而異) //s2: [99 1999 199], len 3, cap: 4 address: 0xc00000c128 (地址可能會改變)

初始狀態下,s2 是 s1 的子切片,共享相同的底層數組。修改s2 的元素會直接影響 s1。然而,append 操作的介入改變了這一情況。當append導致切片容量不足時,Go會重新分配一個更大的底層數組,并將原有數據復制過去。這使得s2不再與s1共享底層數組,因此后續修改s2將不再影響s1。 最后一次對s2的修改只影響了新的底層數組。 注意:地址0xc00000c120和0xc00000c128只是示例,實際地址會因運行環境而異,但關鍵在于append后地址可能發生變化。

立即學習go語言免費學習筆記(深入)”;

因此,理解append操作對切片容量的影響至關重要。它可能導致底層數組的重新分配,進而改變子切片與原切片的關系。

? 版權聲明
THE END
喜歡就支持一下吧
點贊12 分享