這次要說說array,slice,map。雖然前面已經說過了,但是實際使用中發現對這幾個的使用和了解還是不夠詳細
現在再重新看看這幾個類型
array類型
array是固定長度的數組,這個和C語言中的數組是一樣的,使用前必須确定數組長度。但是和C中的數組相比,又是有一些不同的:
1 Go中的數組是值類型,換句話說,如果你将一個數組指派給另外一個數組,那麼,實際上就是将整個數組拷貝一份
2 如果Go中的數組作為函數的參數,那麼實際傳遞的參數是一份數組的拷貝,而不是數組的指針。這個和C要區分開。是以,在Go中如果将數組作為函數的參數傳遞的話,那效率就肯定沒有傳遞指針高了。這個是不是有點陷阱的感覺?
3 array的長度也是Type的一部分,這樣就說明[10]int和[20]int是不一樣的。
array的結構用圖示表示是這樣的:
len表示數組的長度,後面的int儲存的是實際資料
slice類型
看看Effective Go是怎麼誇贊slice的:
Slice是Go程式中最常用的表示序列數組的類型。為什麼最經常用它呢?
1 slice是可變長的
定義完一個slice變量之後,不需要為它的容量而擔心,你随時可以往slice裡面加資料
比如:
v:=[]string{}
v=append(v, "hello")
這裡附帶說一下,slice和array的寫法很容易混
v:=[2]string{"str1", "str2"} //這個是array
m:=[]string{"str1","str2"} //這個是slice
寫法上默念:array有長度slice沒長度,array有長度slice沒長度…
2 slice是一個指針而不是值。
指針比值可就小多了,是以,我們将slice作為函數參數傳遞比将array作為函數參數傳遞會更有性能。
slice是一個指針,它指向的是一個array機構,它有兩個基本函數len和cap。
看下面的圖示:
slice是一個帶有point(指向數組的指針),Len(數組中實際有值的個數),Cap(數組的容量)
比如上面的這個slice,它指向的數組是[3]int,其中的前兩個有值,第三個為空
那麼
len(slic) = 2
cap(slic) = 3
append函數就了解為往slice中加入一個值,如果未達到容量(len<cap)那麼就直接往數組中加值,如果達到容量(len = cap)那麼就增加一個新的元素空間,将值放在裡面
map結構
map結構也經常常用,它和php中的array()幾乎一模一樣,是一個key-value的hash結構。key可以是除了func類型,array,slice,map類型之外的類型。
它的使用也是非常簡單
m:=map[string]string{}
m["key1"] = "val1"
map結構和slice是一樣的,是一個指針。指派的時候是将指針複制給新的變量
map的增删改查操作是這樣的:
package main
import(
"fmt"
)
func main() {
m := map[string]string{"key1":"val1"}
fmt.Println(m)
m["key2"] = "val2"
fmt.Println(m)
p := m["key1"]
fmt.Println(p)
delete(m, "key1")
fmt.Println(m)
}
map 在使用之前必須用 make 來建立(不是 new);一個值為 nil 的 map 是空的,并且不能指派。
func main() {
m = make(map[string]Vertex)
m["Bell Labs"] = Vertex{
40.68433, 74.39967,
}
fmt.Println(m["Bell Labs"])
}
for 循環的 range 格式可以對 slice 或者 map 進行疊代循環。
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}