go的學習記錄(二)--- 數組與數組切片

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

在go語言的學習中,少不了接觸的就是數組和數組切片,並且這兩者的使用也是非常頻繁的。因此如果不能進行很好的理解,或許很容易犯錯。那麼在go中,數組和數組切片都有什麼特點,又是怎麼聲明賦值的,如何使用的呢,下面我就自己的理解總結一下,個人總結可能不全或者有錯,望指點。

一、數組和數組切片的特點

數組是什麼就不用多說了,作為開發人員,這是經常會用到的東西,相信大家都有自己的理解。現在先總結一下數組的特點

1. 數組的長度在定義之後就不可被更改

2. 數組聲明時的長度必須為常量或常量運算式,即可以在編譯器確定長度,分配記憶體

3. 數組的下標從0開始,最後一個元素的下標為(長度-1),即在go中可以寫為 len(arr)-1

4. go語言的數組是實值型別,在作為參數傳遞時會做數組的複製操作。因此作為參數傳遞的時候,被修改的內容不影響原來的數組內容,隻影響傳入函數內的副本

數組切片:是go提供的一種新型的資料類型,它在go語言中的使用有C或C++中的指標的功效。但由於它又不同於指標,所以沒有C或C++中語言的指標操作方式。數組切片的底層是通過數組實現,很容易聯想到C++的vector。

1. 與數組不同,數組切片的長度是可變的,即可以動態分配記憶體空間。但在每次新分配空間的時候,即會對當前的元素進行一次複製

2. go語言提供了內建函數copy用於將內容從一個數組切片複製到另外一個數組切片,但如果兩個數組切片的長度不一樣,則會按照較小的數組切片的個數進行複製。

3. 數組切片與數組一樣,其下標從0開始,最後一個元素的下標為(長度-1),即在go中可以寫為 len(arr)-1

4. go語言提供cap()內建函數可以獲得數組切片分配的空間大小,該值的返回可能與len()返回的大小不同

5. 數組切片提供建立時指定長度和預留儲存空間。在知道數組切片最終能用到的長度時,可以避免切片擴容所引發的記憶體的申請釋放與複製。

6. 數組切片作為參數傳遞時,不會出現記憶體的複製操作,在函數中如果修改了傳入的切片的參數,可以直接修改原數組切片的內容。

二、數組與數組切片的使用

(一) 聲明與建立

數組的定義初始化比較簡單,如下:

1. var arr [10]int//聲明長度為10,類型為int的數組。也可以聲明多維陣列,如:var twod [10][100]int。也可以定義複雜類型數組,如:var st_arr [100]struct {x, y int }

arr[1] = 1 //根據索引賦值

2. arr := [5]int{1,2,3,4,5}//聲明並初始化數組

3. var arr [5]int = [5]int{1,2,3,4,5}//定義並初始化數組

數組切片的定義與初始化,如下:

1. 基於數組建立

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

var slc1 []int = arr[:]//基於數組全部元素建立切片

var slc2 []int = arr[:5]//基於前五個元素建立切片

var slc3 []int = arr[5:]//基於從第五個元素建立切片

var slc4 []int = arr[2:8]//基於從第二個到第八個元素建立切片

以上幾種建立切片的方式,都是基於一種建立規則:基於arr[first:last]這種方式建立數組切片

2. 直接建立

slice1 := make([]int, 5)//建立一個初始元素個數為5的數組切片,元素初始值為0

slice2 := make([]int, 5, 10)//建立一個初始元素個數為5的數組切片,元素初始值為0,並預留10個元素的儲存空間

slice3 := []int{1, 2, 3, 4, 5}//直接建立並初始化包含5個元素的數組切片

3. 基於數組切片建立數組切片

基於數組切片建立數組切片和基於數組建立切片基本相同。但新建立的切片元素個數可以超過舊切片所包含的元素個數,該操作要求新建立切片的元素個數不超過舊切片的容量個數。如:

slice1 :=  make([]int, 5, 10)

slice2 := slice1[:6]


(二)遍曆元素

在go中,無論是數組還是數組切片,都提供了兩種相同的遍曆方式:

1. 使用傳統的for遍曆:

for i := 0; i < len(arr); i++ {

fmt.Println("arr[",i,"] is ", arr[i])

}

2. 使用range關鍵字:

for i, v := range arr {

fmt.Println("arr[",i,"] is ", v)

}


(三) 長度擷取

對於數組和數組切片,go語言提供了內建函數len(),使用方式len(arr),返回當前數組或數組切片的長度。對於數組切片,go語言提供內建函數cap()擷取數組切片的容量

(四)添加元素

對於數組定長,因此沒有添加元素的功能。但數組切片因為動態記憶體的問題,可以提供追加元素。在go語言中提供了內建函數append作為數組切片的元素追加。有以下兩種使用方式:

1. 直接追加元素:

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

slice1 = append(slice1, 5, 6, 7)// append的第一個參數是基於的數組切片。第二個參數是不定參數,可以追加多個元素

2. 數組切片追加數組切片:

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

slice2 := []int{5,6,7,8}

slice1 := append(slice1, slice2…)//這裡要特別注意的是:在第二個數組切片後面需要加三個點,否則會編譯錯誤。主要原因是append第二個參數起都是待追加的元素,而加上三個點的作用就是把slice2的元素按照元素內容列表傳入,而不是以切片作為參數傳入。


(五)作為參數傳遞

1. 數組作為參數

func sort(arr [10] int) {

...

}

該函數的調用要如下:

arr1 := [10]int{8,6,5,4,7,3,9,1,2,10}

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

slice1 := []int{8,6,5,4,7,3,9,1,2,10}

sort(arr) //編譯正常,但由於數組穿參屬於值傳參,在傳參的時候會進行數組複製,因此只修改了sort內部的arr的值,未修改arr1的實際元素值內容

sort(arr2) //編譯錯誤,對於go而言,[10]int 和[5]int 是兩種不同的資料類型

sort(&arr) //編譯錯誤,對於C或C++而言,函數參數定義為int arr[10]這種實際是定義了數組的指標傳入。但go語言中,數組指標和數組是兩種完全不同的類型

sort(slice1)//編譯錯誤,同樣是因為類型不同

2. 數組切片作為參數

func sort(arr []int) {

...

}

arr1 := [10]int{8,6,5,4,7,3,9,1,2,10}

slice1 := []int{8,6,5,4,7,3,9,1,2,10}

sort(arr)//編譯錯誤,類型不同

sort(slice1)//編譯正確,且在sort中對於slice的修改會直接修改到原始的slice。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.