map
是乙個無序的key/value
對的集合,其中key
是唯一的。如果我們在向字典中放入乙個鍵值對的時候其中已經有相同的鍵的話,那麼與此鍵關聯的那個值會被新值替換。
map
的字面量是map[k]t
,其中
注意:鍵型別必須是支援==
比較運算子的資料型別,否則會引起錯誤。即不能是陣列、切片、字典、結構體、函式型別,但是指標和介面型別可以。對於值的型別,沒有限制。
map
可以通過測試key
是否相等來判斷是否已經存在。雖然浮點數型別也是支援相等運算子比較的,但最好別使用將浮點數作為key
,可能出現nan
和任何浮點數都不相等。
含有陣列切片的結構體不能作為示例:key
,只包含內建型別的struct
是可以作為key
的。如果要用結構體作為key
可以提供key()
和hash()
方法,這樣可以通過結構體的域計算出唯一的數字或者字串的key
。
var m1 map[string]int
m1 = map[string]int
var m2 map[string]int = map[string]int{}
m2["a"] = 3
m2["b"] = 4
m3 := map[string]int
m4 := map[string]int{}
m4["a"] = 1
m4["b"] = 2
複製**
與切片型別相同,字典型別屬於引用型別。它的零值即為nil
。(詳見零值問題)
map
可以根據新增的key-value
對動態的伸縮,不存在固定長度或者最大限制。但是你可以選擇標明map
的初始容量capacity
:
m1 := make(map[string]int)
m1["a"] = 1
m1["b"] =2
m2 := make(map[string]int, 100)
複製**
不要使用對於new
,永遠用make
來構造map
。如果你錯誤的使用new()
分配了乙個引用物件,你會獲得乙個空引用的指標,相當於宣告了乙個未初始化的變數並且取了它的位址。
map
來說,如果獲取不存在的 key,就以它的值型別的空值(或稱預設值)作為值結果。那麼,我們在不知道 map 確切的情況下,怎麼知道要取的 key 是否存在呢?
m1 := map[string]int
x := m1["a"] // 1
x, ok := m1["a"] // 1 true _, ok := m1["a"] 可以用來判斷 key 是否存在。
y := m1["c"] // 0
y, ok := m1["c"] // 0 false
複製**
map
中的元素並不是乙個變數,因此我們不能對map
的元素進行取址操作。禁止對map
元素取址的原因是map
可能隨著元素數量的增長而重新分配更大的記憶體空間,從而可能導致之前的位址無效:
&m1 // 沒問題
&m1["a"] // cannot take the address of m1["a"]
複製**
m1 := map[string]int
m1["a"] = 3
fmt.println(m1) // map[a:3 b:2]
m1["c"] = 4
fmt.println(m1) // map[c:4 a:3 b:2]
複製**
另外,x += y
和x++
等簡短賦值語法也可以用在map
。
delete
操作是安全的,有則刪除,無則不做。
m1 := map[string]int
delete(m1, "a") // 有則刪除
delete(m1, "c") // 無則不做
複製**
map
的迭代順序是不確定的,並且不同的雜湊函式實現可能導致不同的遍歷順序。在實踐中,遍歷的順序是隨機的,每一次遍歷的順序都不相同。這是故意的,每次都使用隨機的遍歷順序可以強制要求程式不會依賴具體的雜湊函式實現。
for key, value := range map1
// 如果只想獲取 key,你可以這麼使用:
for key := range map1
複製**
map
是無序的,如果你想按順序遍歷map
,需要將key
(或者value
)拷貝到乙個切片,再對切片排序(使用sort
包):
package main
import (
"fmt"
"sort"
)var m = map[string]int
func
main()
keys := make(string, 0, len(m))
for key := range m
sort.strings(keys)
for _, key := range keys
}複製**
但是如果你想要乙個排序的列表,最好使用結構體切片,這樣會更有效:
type name struct
複製**
切片的元素是map
型別:
package main
import
"fmt"
func
main()
fmt.println(myslice) // [map[a:10 b:20 c:30] map[a:10 b:20 c:30] map[a:10 b:20 c:30]]
}複製**
當然,map
的value
也可以是切片型別:
var m1 map[string]int
複製**
和slice
一樣,map
之間也不能進行相等比較,唯一的例外是和nil
進行比較。要判斷兩個map
是否包含相同的key
和value
,我們必須通過乙個迴圈實現:
func
equal
(x, y map[string]int)
bool
for k, xv := range x
}return
true
}複製**
map
型別的零值是nil
,也就是沒有引用任何雜湊表。map
上的大部分操作,包括查詢、刪除、len
和range
迴圈都可以安全工作在nil
值的map
上,它們的行為和乙個空的map
類似。但是向乙個nil
值的map
存入元素將導致乙個panic
異常。在向map
存資料前必須先建立map
。
var m1 map[string]int
// nil
m2 := map[string]int{} // 空map
fmt.println(m1 == nil) // true 0
fmt.println(m2 == nil) // false 0
m1["a"] = 1
// panic: assignment to entry in nil map
m2["a"] = 1
// 正常
複製**
go
語言中並沒有set
型別,由於map
中的key
也是不相同的,可以將忽略value
的map
當成set
。 go學習筆記(12)
在學習golang的websocket的時候,出現了這樣錯誤。這個錯誤產生了很大的疑惑。為什麼會出錯?由於前端作為測試使用,所以編寫乙個較為簡單的測試用例即可。但js裡面的websocket 傳送採取了二進位制去傳送。ws.binarytype arraybuffer 監聽了本地埠6336 由於是測...
GO學習筆記 對映 map
go語言中提供的對映關係容器為map,其內部使用雜湊表 hash 實現。go語言中 map的定義語法如下 map keytype valuetype 其中,map型別的變數預設初始值為nil,需要使用make 函式來分配記憶體。語法為 make map keytype valuetype,cap 其...
GO學習筆記之 map
map是 key value 資料結構,又稱為字段或者關聯陣列。類似其他程式語言的集合 在程式設計中經常使用。基本語法 map是無序的 var map變數名 map keytype valuetype key可以是什麼型別 golang中的 map,的 key可以是很多種型別,比如 bool 數字,...