1. 程式人生 > >[Golang]slice的用法以及和陣列的區別

[Golang]slice的用法以及和陣列的區別

說明

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傳引用,這一點需要注意。後面會詳細講值語義帶來的問題。

擴充套件閱讀: