[Golang]slice的用法以及和陣列的區別
阿新 • • 發佈:2019-02-01
說明
slice是go的一個語言特性,其實有點類似於cpp的vector,可變長度,可以擴充套件空間。今天詳細看了下,做下總結。
slice本質上是一個區間,原型是[]T,大致的實現是這樣的:
type slice struct {
first *T
len int
cap int
}
可以看到的是是一個指向陣列的指標,那麼在修改slice的時候會改變陣列的值。
用法
和陣列的用法差別不是太大。
- 基於陣列的建立:
var myArrary [3]int = [3]int{1,2,3}
var mySlice []int = myArray[:2 ] //[first:last]方式,不足時補0
- 直接建立:
mySlice = make([]int, 5)//建立了長度為5初值為0的切片
mySlice = make([]int, 5, 10)//建立了長度為5,容量為10的切片
- 函式
len() 返回元素的個數
cap()返回容器大小
append()新增元素
mySlice = append(mySlice, 1, 2, 3) //後者的引數型別其實是不定引數
mySlice2 = []int{7, 8, 9}
mySlice = append(mySlice, mySlice2...) 加入...表示打散後傳入
copy()深複製slice
slice1 := []int{1, 2, 3, 4, 5}
slice2 := []int{1, 2, 3}
copy(slice2, slice1)//copy slice的前3個元素到slice2
slice2 = slice1 //會複製一份引用給slice2
- 和陣列區別
func arrayModify(array [5]int) {
newArray := array
newArray[0] = 88
}
func sliceModify(slice []int) {
newSlice := slice
newSlice[0] = 88
}
func main() {
array := [5]int{1, 2, 3, 4, 5}
slice := []int{1, 2, 3, 4, 5}
arrayModify(array)
sliceModify(slice)
fmt.Println(array)
fmt.Println(slice)
}
// [1 2 3 4 5]
// [88 2 3 4 5]
可以看到的是陣列傳的是值,不會改變元素的值,這一點和c/cpp不同,而雖然slice也是值語義,但是其本身是指標型別的,所以會改變值,但不意味著slice傳引用,這一點需要注意。後面會詳細講值語義帶來的問題。
擴充套件閱讀: