先看**:
package mainimport (
"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 mainimport (
"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 mainimport (
"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函式獲得,切片是引用型別,因此...