1. 程式人生 > 其它 >轉--Golang語言--複合資料

轉--Golang語言--複合資料

1、array

陣列的型別格式為單個數據單元型別+長度構成,如 [2]int,其中 [2] 代表陣列的長度,而 int 代表每個單元都是整形。

陣列的元素操作也是通過操作下標,即 arr[1] ,取出陣列 arr 中的第2個元素,陣列下標從0開始算起。

陣列的長度可以通過 len(arr) 獲取陣列 arr 的長度。

1-1 宣告和初始化

陣列宣告格式為 var 陣列名 [陣列長度]元素型別

例如:

var arr [2]int
arr[0] = 1 // 宣告以後,就可以使用index進行賦值

宣告陣列後,未進行初始化,則每個資料單元的初值是單元資料型別的預設值,例如 int 就是 0 ,string 是空 ""

宣告的同時也可以初始化

var arr [2]int = [2]int{1, 2}

初始化資料的格式為: 陣列型別 + 大括號 + 陣列的資料

也可以使用:=來縮寫

arr := [2]int{1, 2}

使用:=可以省略陣列長度,而使用 [...] 讓Go自動計算陣列長度

arr := [...]int{1, 2}

PS:Go中的 ... 在別的地方還有很多,通常代表的意思是編譯或執行時確定數目。

1-2 陣列的巢狀

陣列也可以作為另外一個數組的元素,這樣就形成多維陣列(巢狀陣列)

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

可以簡寫為

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

同樣巢狀陣列的同緯度下的元素型別必須一致,例如

var arr [2][2]int arr0 := [2]int{1, 2} arr[0] = arr0

arr1 := [1]int{1} arr[1] = arr1 // 編譯報錯:cannot use arr1 (type [1]int) as type [2]int in assignment

1-3 陣列的長度

陣列長度必須宣告時給出,一旦給出以後便不能發生改變,可以通過len函式來獲取陣列的長度

1-4 陣列的越界

如果下標小於0或者大於等於陣列的長度

a、下標是數值常量,則編譯報錯:index out of bounds

b、下標是動態變數,則執行的時候檢測,錯誤資訊是 runtime error : index out of range

1-5 陣列的賦值

array 賦值不同於 string , string 因為不能改變,所以只用傳字串的地址即可,而 array 因為能改變,所以要將整個內容複製,在記憶體中會有2份資料存在

arr1 := [2]int{1, 2} var arr2 [2]int

arr2 = arr1 arr2[1] = 3 fmt.Print(arr1[1]) // 輸出2

因為陣列賦值需要佔用空間,所以大多數情況是使用slice,用切片傳遞陣列的地址的方式來減小記憶體的消耗。

2、slice

slice可以認為是個特殊的類陣列的結構,其指向一個數組型別的資料,使用方式也同陣列,越界報同陣列一樣的錯誤

2-1 slice 的宣告

var s []int //不同於陣列,長度是不指明的,如果指明則是一個數組

宣告 slice 後,未進行初始化,則 slice 的值是 nil ,可以通過make進行預設值初始化,也可以使用具體值初始化。

預設值初始化(以下初始化都使用簡短格式:=)

s := make([]int, 4, 4) // 第一個4為切片的長度,第二個為切片的容量,下面有解釋

// 等同於 s := []int{0, 0, 0, 0}

具體值初始化的3種情況

a、指向已經存在的陣列

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

s := arr[1:3]

b、建立一個(匿名)陣列並且指向這個陣列

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

c、基於另一個slice

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

s2 := s1[2:4]

2-2 slice 的結構

slice 的結構包含3部分:指向底層資料(起始下標)的指標、長度、容量。

長度同陣列一樣,使用len函式,容量則用cap函式

Array_a := [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'} Slice_a := Array_a[2:5]

例子的結構如下圖所示(圖片來自https://github.com/astaxie/build-web-application-with-golang

按照數學上區間定義理解就是,array[i:j]的區間應該是[i,j),即包含的元素索引是 i <= index < j

上例中的 Array_a[2:5] 則包含的元素是:Array_a[2],Array_a[3] ,Array_a[4]

Slice_a 的 len() 等於 j - i

Slice_a 的 cap() 等於 len(Array_a) - i

如果i為0,j為array的長度,則可以忽略

Slice_a := Array_a[:] // 則包含陣列的所有元素

2-3 slice的一些操作函式

除了上面已經說的make、len、cap函式之外,slice還支援append、copy操作函式

copy(dst, src) 從源src中複製元素到目標dst,並且返回複製的元素的個數,在Go語言中,幾乎都遵循這樣的次序,即目標引數在前,源引數再後

copy支援將string型別複製到位元組切片,除此之外都必須型別相同

var byte_slice = make([]byte, 2)

copy(byte_slice, "hi")

append(dst, src) 將源src追加到目標dst中,其中源src可以是一個或者多個單一型別的值

int_slice := []int{1}

int_slice = append(int_slice, 2, 3) // [1, 2, 3]

也可以使另外一個切片,但是切片後面需要指定...特殊標記

int_slice := []int{1}

int_slice2 := []int{2, 3} int_slice = append(int_slice, int_slice2...) // [1, 2, 3]

通樣append也支援將string型別複製到位元組切片,後面需要指定...特殊標記

var byte_slice = []byte("hello") byte_slice = append(byte_slice, "world"...)

2-4 slice 的一些快捷操作

//在i位置後插入元素x

slice = append(slice[:i], append([]T{x}, slice[i:]...)...) // T的意思代表是某個資料型別

//在i位置後插入切片

slice1 = append(slice[:i], append(slice2, slice[i:]...)...)

//在i位置後插入j個空元素

slice = append(slice[:i], append(make([]T, j), lice[i:]...)...)

//切片追加單個元素

slice = append(slice, x)

//切片追加切片內容

slice1 = append(slice1, slice2...)

//切片追加 j個空元素

slice = append(slice, make([]T, j)...)

//複製切片

slice2 = make([]T, len(slice1))

copy(slice2, slice1)

//刪除切片中的第i個元素

slice = append(slice[:i], slice[i+1:]...)

//刪除切片中的指定元素集合[i:j]

slice = append(slice[:i], slice[j:]...)

// 彈出第一個元素

x, slice = slice[0], slice[1:]

// 彈出最後一個元素

x, slice = slice[len(slice)-1], slice[:len(slice)-1]

3、map

map在一些語言中稱之為字典(Dictionary),也有稱之為散列表(Hash Table) ,指的是一些型別的值到另一個型別的值的對應關係。

3-1 宣告和初始化

map宣告格式為 var map名 map[索引型別]元素型別

例如:

var map1 map[int]string

宣告map後,未進行初始化,則map的值nil,還不能進行賦值,需要用make進行初始化

map1 = make(map[int]string)

宣告的同時也可以初始化

var map1 map[int]string = make(map[int]string)

也可以使用:=來縮寫

map1 := make(map[int]string)

也可以不用make,直接用值初始化

map1 := map[int]string{}

使用指定值初始化的時候,需要用key:value的格式

map1 := map[int]string{1:"1",2:"2"}

3-2 map操作

內建函式len通用可以用在map上,返回當前map中有多少個元素

map因為沒有記憶體限制,可以很方便的新增,也可以很方便的刪除,刪除需要用delete,例如刪除map1的key為1的元素為

delete(map1, 1)

獲取map中的key的value

v := map[key]

判斷是否存在某個key

v, ok := map[key]

key存在map中, v = key 的 value,ok = true

key不存在map中, v = T(default),ok = false

新增或者更改value

map[key] = value

注意 map 不保證 key - value 的存放順序

key必須是支援比較運算子(== !=)的型別,如number、string、pointer、array、struct 、interface(介面實現型別必須支援比較運算子),不能是function、map、slice