go 中的slice與數組


go 中的slice與數組

數組

go中的數組與C語言中的數組類似,但是不同的是C中的數組名其實還是指針,在作為參數傳遞的過程中會退化為指針,而go語言則是在編譯期間就確定其大小,然后始終是作為值傳遞的。

初始化

  • [5] int {1,2,3,4,5}
    長度為5的數組,其元素值依次為:1,2,3,4,5
  • [5] int {1,2}
    長度為5的數組,其元素值依次為:1,2,0,0,0 。在初始化時沒有指定初值的元素將會賦值為其元素類型int的默認值0,string的默認值是""
  • [...] int {1,2,3,4,5}
    長度為5的數組,其長度是根據初始化時指定的元素個數決定的
  • [5] int { 2:1,3:2,4:3}
    長度為5的數組,key:value,其元素值依次為:0,0,1,2,3。在初始化時指定了2,3,4索引中對應的值:1,2,3
  • [...] int {2:1,4:3}
    長度為5的數組,起元素值依次為:0,0,1,0,3。由於指定了最大索引4對應的值3,根據初始化的元素個數確定其長度為5

作為參數傳遞

例如:

package main

import (
	"fmt"
	"reflect"
)

func modifySlice(array []int) {
	array[0] = 10
}

func modifyArr(array [5]int) {
	array[0] = 10
}

func modifyPt(array *[5]int){   // 作為指針傳遞
    (*array)[0] = 10
}

func main(){
	arr := [...]int{1,2,3,4,5}
	fmt.Println(reflect.TypeOf(arr))
	modifyArr(arr)
	fmt.Println("In main(), arr values:", arr)
	modifyPt(&arr)
	fmt.Println("In main(), arr values:", arr)

	sli := []int{1,2,3,4,5}
	fmt.Println(reflect.TypeOf(sli))
	modifySlice(sli)
	fmt.Println("In main(), sli values:", sli)
}

// 輸出結果為
//[5]int
//In main(), arr values: [1 2 3 4 5]
//In main(), arr values: [10 2 3 4 5]
//[]int
//5
//In main(), sli values: [10 2 3 4 5]

slice 切片

從上面的例子中可以看出slice作為參數傳遞的是指針,因此傳遞速度會快很多。

但是數組作為一個固定長度的數據類型,在使用中有很多不方便的地方,因此go提供了一個很類似python 中的list的數據類型slice

從名字也能看出來slice支持切片操作

sli := []int{1,2,3,4,5}
sli = sli[:3]

還支持append操作

sli = append(sli, 6)
sli = append(sli, sli2)

如果要實現類似數組的值傳遞的功能,可以利用 copy 函數

sli1 := make([]int, len(sli))
copt(sli1, sli)

初始化

  • 可以通過make初始化
sli := make([]int, 5, 10)  // 5 是其長度,10 是其容量(可選),分別可以通過 len(sli)  cap(sli) 獲取
  • 直接初始化(初始長度為0)
var sli []int      // sli = nil
  • 從數組或slice初始化
sli := arr[:]     // sli 的修改也會影響到arr

對比

從上面的內容可以看出數組與切片有以下區別

  • 數組定長,定義的時候就需要確定,切片不定長
  • 切片支持append、copy、切片操作
  • 數組作為參數的時候是默認進行拷貝,值傳遞,而切片是引用傳遞

順便說一下,slice的數據結構類似下面:

+--------------------+
| data pointer |
+--------------------+
| len |
+--------------------+
| cap |
+--------------------+

然后擴容方式與vector類似,1024字節以下是每次cap增加一倍,1024以上是每次cap增加1/4


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM