go append切片之坑

2022-08-11 07:00:13 字數 1603 閱讀 3683

先看**:

package main

import (

"fmt"

)func main()

var part1 = basearr[:1] // (1)

var part2 = basearr[1:]

var result int

for i := 0; i < len(part2); i++

fmt.println(result)

}

預期結果:[[1 2] [1 3]]

實際結果:[[1 3] [1 3]]

為什麼會這個樣子呢?

關於切片,

切片包括三部分,指標+長度+容量, 切片本身不包含資料,而是由指標指向一片底層資料

這種結構的帶來好處是當把切片作為函式引數時,只會拷貝切片本身,速度非常快。

但是在把切片的某部分賦給另外的切片時,修改當前切片的值,原來的切片指向的底層陣列就會發生變化。

舉個例子,

a := int

b :=  a[1:2],

b[0] = 4,

列印a會發現結果是[1,4,3]

即新的切片b只是改變了對原有切片的指標位置,但是仍然指向底層陣列int

而len(b) = 新切片結束位置 - 新切片起點位置 = 1

cap(b) =  原切片結束位置 - 新切片結束位置 = 2

1)如果slice的容量還有剩餘,元素1直接追加到slice指向的底層陣列。

故而最後的result = [[1,3],[1,3]]

通過增加兩行列印即可驗證,

package main

import (

"fmt"

)func main()

var part1 = basearr[:1]

var part2 = basearr[1:]

var result int

for i := 0; i < len(part2); i++

fmt.println(result)

}

輸出:the cap of part1: 3

the basearr is: [1 2 3]

the cap of part1: 3

the basearr is: [1 3 3]

[[1 3] [1 3]]

那麼如何能得到預期的結果呢,使用make & copy函式,

package main

import (

"fmt"

)func main()

var part1 = make(int, 1)

copy(part1, basearr[:1])

var part2 = basearr[1:]

var result int

for i := 0; i < len(part2); i++

fmt.println(result)

}

需要注意,copy函式在執行的時候會取len(src)和len(dst)的最小長度進行複製。

GO 切片實力踩坑

go 語言的切片這兩天用了用,可以支援切割陣列的中間部分.但今天使用中,出了 bug,查了半天,發現是切片的問題,簡單寫個 demo 復現當時的情況 package main import fmt func main b a 2 4 b 0 9 fmt.println a 你以為輸出的是什麼?來,看...

GO 切片實力踩坑

go 語言的切片這兩天用了用,可以支援切割陣列的中間部分.但今天使用中,出了 bug,查了半天,發現是切片的問題,簡單寫個 demo 復現當時的情況 package main import fmt func main b a 2 4 b 0 9 fmt.println a 你以為輸出的是什麼?來,看...

golang中切片 slice 的坑

golang中陣列的長度是不可以變得,但是某些場合就不使用了,go提供了一種靈活,功能強悍的型別 切片,切片中有兩種概念 一種是len長度,二是cap容量,長度是已經被賦值的最大下標 1,可以通過len函式獲得切片的長度。容量是指切片最大可容納多少個元素,可以通過cap函式獲得,切片是引用型別,因此...