這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
Go 語言支援複合類型:
- 數組:array
- 切片:slice
- 指標:pointer
- 字典:map
- 通道:chan
- 結構體:struct
- 介面:interface
1. array
同一類型資料的集合
var arr [n]type //聲明type類型一維數組
var arr [m][n]type //聲明type類型二維數組
多維陣列以此類推
也可以用 := 聲明
arr := [n]type{元素1[,元素2, ...]} 其中n可以用 "..." 三個點表示,系統會根據元素個數來確定
下標只能為 int 類型,而 php 還支援 string 類型的下標
1.1 數組長度 len(arr)
註:數組長度在定義後就不可變
1.2 遍曆:
a. 迴圈通過過數組下標訪問 arr[0] ~ arr[(len(arr))]
b. range arr, 有兩個傳回值 第一個為數組下標,第二個為元素的值,與php遍曆數組相似
for k, v := range array { fmt.Printf("arr[%d] = %d \t", k, v) }
foreach ($arr as $k => $v) { printf("arr[%d] = %d \t", $k, $v); //echo '$arr[' . $k . "] = " . $v . "\t"; }
1.3 數組在賦值與傳遞參數時,都會產生一個數組副本,而不是使用它的指標
2. slice
在定義 array 時,其長度是固定的,並且 array 是一個實值型別
而 slice 是一個可變的數組,但是一個參考型別
2.1 產生slice的三種方式
a. 聲明與 array 一樣,不過不需要指定長度
var slice1 []int
slice2 := []int {元素1[, 元素2, ...]}
b. 從數組(或者切片或者字串)中擷取 arr[i:j] i=數組的開始位置,j=結束位結果,j-i=切片的長度,i和j都可以省略,省略時 i=0, j=len(arr),i是從0開始,j是從1開始
a b c d e f
i 0 1 2 3 4 5
j 1 2 3 4 5 6
slice1 := arr[:] //arr[0:6]/arr[0:] slice2 := arr[1:1] //[] slice4 := arr3[1:3] //b c slice5 := arr3[:5] // = arr3[0:5]
c. make
slice1 := make([]int, 5, 10)
len(slice1) = 5, cap(slice1) = 10, 元素的初始值為0
2.2 相關函數
len(slice): 返回 slice 的元素個數(長度)
cap(slice): 返回 slice 的分配空間大小
append(slice1, slice2...): 把 slice2 追加到 slice1 產生新的 slice, 若 slice2 是變數時,不能省略...,相當於 append(slice1, a[, b, ...])
copy(目標slice, 源slice): 以最小的切片元素個數為準,將源 slice 複製到 目標 slice
2.3 cap - len = 0 時,系統將動態分配新的數組空間,即切片會自動處理儲存空間不足的問題
2.4 遍曆與 array 一樣
2.5 在傳遞參數時,傳遞的為指標
3. map
在Java/python等語言中都有提供
暫時可以理解為:一張無序的表
其長度也不固定,也是參考型別,在賦值與傳參過程中,指向同一地址
key1 value1
key2 value2
... ...
3.1 聲明與建立
var map變數名 map[鍵type] 值type //鍵type可以為int或者string,值type,需要make初始化
map變數名 = make(map[鍵type] 值type)
//或者
map變數名 := make(map[鍵type] 值type) [{鍵1:值1}[,{鍵2:值2},...}] //[]中為可選
3.2 相關操作
賦值: map變數名[鍵] = 值
讀取: map變數名[鍵] //如果鍵不存在,返回nil
刪除索引值對: delete(map變數名, 鍵) //如果鍵不存在,無影響
取map的元素個數: len(map變數名)
不能用cap函數
note_type_2.go code list
package mainimport "fmt"func main() {//先聲明後賦值var arr [3]int//arr = {1, 2, 3} //不能這樣賦值給數組arr[0] = 1arr[1] = 2arr[2] = 3//arr[3] = 4 //compile error: index out of boundsfmt.Println(arr[0], arr[0:2]) //輸出 1 [1 2]//arr1 := [3]int{4, 5, 6}arr1 := [...]int{4, 5, 6} //和上面結果一樣fmt.Printf("arr[1] = %d \n", arr1[1]) //輸出 arr[1] = 5//遍曆數組for i := 0; i < len(arr); i++ {fmt.Printf("arr[%d] = %d \t", i, arr[i])}fmt.Println()for k, v := range arr1 {fmt.Printf("arr[%d] = %d \t", k, v)}fmt.Println()changeValue(arr1)fmt.Println("result: ", arr1) //result: [4 5 6] 值不發生改變//二維數組arr2 := [2][3]int{{1, 2}, {4, 5, 6}}fmt.Println("len(arr2) = ", len(arr2)) //len(arr2) = 2fmt.Println("len(arr2[0]) = ", len(arr2[0])) //len(arr2[0]) = 3for i, v := range arr2 {fmt.Println(i, v)}for i1, v1 := range arr2 {for i2, v2 := range v1 {fmt.Printf("arr2[%d][%d] = %d \t", i1, i2, v2)}fmt.Println()}//sliceslice1 := []byte {'b', 'b'}slice1[0] = 'a' //如果只聲明了slice,無元素時,直接通過下標賦值會compile errorfmt.Printf("slice1[0] = %c \n", slice1[0]) //slice1[0] = aarr3 := [...]byte {'a', 'b', 'c', 'd', 'e', 'f'}slice2 := arr3[:] // = arr3[0:]fmt.Println("slice2 = ", slice2)slice3 := arr3[1:1] //空fmt.Println("slice3 = ", slice3)slice4 := arr3[1:3] //b cfmt.Println("slice4 = ", slice4)slice5 := arr3[:5] // = arr3[0:5]fmt.Println("slice5 = ", slice5)slice6 := slice5[1:2] //bfmt.Println("slice6 = ", slice6)str := "hello"slice7 := str[4:5] //ofmt.Printf("slice7[0] = %s \n", slice7) //slice7[0] = ofmt.Println("len(slice4) = ", len(slice4)) //len(slice4) = 2fmt.Println("cap(slice4) = ", cap(slice4)) //cap(slice4) = 5//slice8 := append(slice4, 'a', 'd') //b c a dslice9 := []byte {'a', 'b'}slice8 := append(slice4, slice9...) //b c a d = append(slice4, 'a', 'b')fmt.Printf("slice8[2] = %c \n", slice8[2]) //slice8[2] = afmt.Println("len(slice8) = ", len(slice8)) //len(slice8) = 4slice10 := []byte {'x', 'y', 'z'}copy(slice10, slice9)for i, v := range slice10 {fmt.Printf("slice10[%d] = %c \t", i, v) //a b z}fmt.Println()/*//slice9 = a, b; slice10 = x, y,z copy(slice9, slice10)for i, v := range slice9 {fmt.Printf("slice9[%d] = %c \t", i, v) //x y }*/s1 := make([]int, 5, 10)fmt.Println("len, cap = ", len(s1), ", ", cap(s1)) //len, cap = 5, 10s2 := []int {1, 2, 3}changeValue2(s2)fmt.Println("result2: ", s2) //result2: [5 2 3] 結果會發生改變//mapvar map1 map[string] string//map1["a"] = "123" //如果不初始化,會出現異常 panic: runtime error: assignment to entry in nil mapmap1 = make(map[string] string)map1["a"] = "123"fmt.Println("map1 = ", map1) //map1 = map[a:123]fmt.Println(map1["b"]) // (nil)b, found := map1["b"] //found 為 bool 值, true = foundif found {fmt.Println("found, and the value = ", b)} else {fmt.Println("not found")}map1["b"] = "456"fmt.Println("map1 = ", map1) //map1 = map[a:123 b:456]delete(map1, "b") //刪除鍵為"a"的索引值對fmt.Println("map1 = ", map1) //map1 = map[b:456]fmt.Println("len(map1) = ", len(map1)) //len(map1) = 1//fmt.Println("cap(map1) = ", cap(map1)) // invalid argument map1 (type map[string]string) for capmap2 := map1map2["a"] = "789"fmt.Println("map1 = ", map1) //map1 = map[a:789],其值為發生改變,因為map2和map1是同一地址空間}func changeValue(arr [3]int) {arr[0] = 100fmt.Println("changeValue: ", arr) //changeValue: [100 5 6]}func changeValue2(slc []int) {slc[0] = 5fmt.Println("changeValue2: ", slc) //changeValue2: [5 2 3]}
運行結果: