array
數組聲明和賦值
go的數組聲明跟C語言很相似,除了數組類型放在變量名後面【這點跟變量的聲明一樣】。
數組的定義格式:
//一維數組
var 數組名[n] 數組類型 //需要注意的是:'[n]'可以寫成'[...]',go會自動根據元素個數來計算長度,
//我猜應該是編譯的時候計算的吧
//二維數組
var 數組名[2][n]int{[n]數組類型{..},[n]數組類型{}}
數組的聲明和賦值:
//一維數組
var ar = [5]byte {'a', 'b', 'c', 'd', 'e'}
//也可以
ar := [5]byte {'a', 'b', 'c', 'd', 'e'}//注意這個只能是函數內部定義,也就是局部變量
//二維數組
var arr = [2][4]int{ [4]int{1, 2, 3}, [4]int{4, 5, 6} }
//可以省略{}中的[4]int
var arr = [2][4]int{ {1, 2, 3}, {4, 5, 6} }
數組容量和長度
Go中,函數cap()
和len()
均輸出數組的容量跟長度,不難發現數組的容量跟長度是一樣的。
slice
Go的數組用的是C的思想,那麼slice則用的是java的思想。slice在內存中的本質其實也是數組,體現爲連續的內存塊。但是它與數組又有不同,數組一旦定義好了,它的大小也就固定了;而slice的大小是可以變化的,但又不是java中真正意義上的動態數組,而是數組的引用,是一個引用類型。
slice的聲明跟數組的聲明一樣,只是不需要長度。
slice的聲明:
var fslice []int//注意這裏沒有長度,所以不要把它認爲是數組哦
//同樣也可以
slice := []int{1,2,3}
sliced的聲明和賦值:
var ar = []byte {'a', 'b', 'c', 'd', 'e'}
//也可以
ar := []byte {'a', 'b', 'c', 'd', 'e'}//注意這個只能是函數內部定義,也就是局部變量
我們也可以從一個數組或者一個已經存在的slice中再次聲明。slice 通過 array[i:j] 來獲取,其中 i是數組的開始位置, j 是結束位置,但不包含 array[j] ,它的長度是 j-i
//聲明一個數組
var Array_ori = [11]byte {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'}
//聲明兩個slice
var Slice_a,Slice_b[]byte
//Slice_a指向數組Array_ori,第2個元素`Array_ori[2-1]`開始,第5個元素`Array_ori[5-1]`結束
slice_a = Array_ori[2:5]
//slice1指向數組Slice_a,第3個元素`Slice_a[3-1]`開始,第5個元素`Slice_a[5-1]`結束
slice_b = Slice_a[3:5]//先自己想下會輸出什麼
其數據結構如下所示:
根據上圖,不難推導出Array_ori, slice_a, slice_b的內容輸出如下:
Array_ori:[a b c d e f g h i j k]
slice_a:[c d e]
slice_b:[f g]
是不是對slice有種似曾相識的感覺,沒錯,感覺跟C的指針很像,一開始學的時候感覺有java的動態數組的思想,這會又有C的指針思想,寶寶好凌亂啊。
slice的幾個內置函數
- cap():slice的最大容量,上例中的 Slice_a和Slice_b的cap()值分別爲8和5。正式由於Slice_a容量爲8,所以給Slice_b的賦值是有效的
- len():slice的長度,上例已有介紹,Slice_a和Slice_b的len()值分別爲3和2
- append():向 slice 裏面追加一個或者多個元素,然後返回一個和 slice 一樣類型的slice
- copy():函數 copy 從源 slice 的 src 中複製元素到目標 dst ,並且返回複製的元素的個數
make和new操作
make跟new都可以用於內存分配。
- new用於各種類型的內存分配,本質上跟java的new的功能是一樣的。new(T)返回了一個指針,指向新分配的類型 T 的零值。
- make只能用於給slice、map和channel類型的內存分配,並且返回一個有初始值(非零)的 T 類型,而不是指針 T。
map
map跟Pythoon的字典概念一樣,凌亂了,又開始有python的思想了。關鍵是不懂python啊,不過沒關係,後面我會學它的。
map的格式:
map[keyType] valueType
map的聲明:
- 使用map關鍵字:
var map_variable map[keyType]valueType
- 使用 make 函數,返回一個 map 給 map_variable:
map_variable = make(map[keyType]valueType)
map的聲明和賦值
var numbers map[string] int
// 另一種 map 的聲明方式
numbers := make(map[string]int)
numbers["one"] = 1 //賦值 key是“one”,值是1
numbers["ten"] = 10 //賦值
numbers["three"] = 3
fmt.Println("第三個數字是: ", numbers["three"]) // 讀取數據打印出來如:第三個數字是: 3
map注意事項:
- map 是無序的,每次打印出來的 map 都會不一樣,它不能通過 index 獲取,而必須通過 key 獲取
- map 的長度是不固定的,也就是和 slice 一樣,也是一種引用類型
- 內置的 len 函數同樣適用於 map ,返回 map 擁有的 key 的數量
- map 的值可以很方便的修改,通過 numbers[“one”]=11 可以很容易的把 key 爲 one的字典值改爲 11
- map 的初始化可以通過 key:val 的方式初始化值,同時 map 內置有判斷是否存在 key 的方式;比如:
map_variable := map[string]string{"a": "1", "b": "2", "c": "3"}
- 通過 delete 刪除 map 的元素,函數原型
delete(map_variable, key)