認真一點學 Go:9. 內建集合 - map

瀟灑哥老苗發表於2021-09-29

收錄於 《Go 基礎系列》,作者:瀟灑哥老苗。

學到什麼

  1. 什麼是 map?

  2. 如何建立 map?

  3. 判斷鍵是否存在?

  4. 如何獲取 map 長度?

  5. 如何遍歷 map?

  6. 如何刪除鍵/值對?

  7. map 是引用型別還是值型別?

概念

map 是一種鍵(key)/值(value)對的無序集合,在其它語言中稱為字典、關聯陣列、雜湊表等。當給定了鍵可以快速定位到值,而且鍵必須唯一的,不能出現相同。

宣告

格式: var 變數名 map[鍵型別][值型別]

舉例:宣告瞭一個鍵為 int 型別,值為 string 型別的 map。


var dic map[int]string

注:未初始化,dic 為 nil。

鍵型別限制

宣告 map 時,鍵不是所有型別都支援,它只支援可以使用 !=== 運算子比較的型別。講的這,也明白了在 Go 語言中不是所有型別都可以進行比較

哪些型別不能進行比較?

  • 函式

  • map

  • 切片

  • 元素是函式、map、切片的陣列

  • 欄位中包含函式、map、切片的結構體

初始化

初始化 map 有兩種方式,第一種使用 make 函式,第二種是宣告 map 時,初始化具體的鍵和值。如果 map 未初始化是不能存取值的,不然編譯器報錯。

1. make 函式


dic := make(map[int]string)

現在就可以存值了,初始化後的 map 會根據新增的鍵值動態伸縮,使用 len 函式獲取長度。


// collection/map-make.go

dic := make(map[int]string)

dic[1] = "lao"

dic[3] = "miao"

fmt.Println("dic長度:", len(dic))

// 輸出

dic長度: 2

在初始化時,可以提前定義好 map 所需要的容量(空間大小),當新增的鍵值超過容量時自動加一


// collection/map-make-cap.go

dic := make(map[int]string, 10)

// 容量為 10 ,存了 1 個

dic[1] = "lao"

fmt.Println("dic長度:", len(dic))

// 輸出

dic長度: 1

2. 宣告時初始化

宣告瞭一個鍵為 string 型別, 值為 int 型別的 map,並初始化了 3 個鍵/值對。


// collection/map-init.go

m := map[string]int{

    "a": 2,

    "b": 3,

    "c": 4,

}

fmt.Println("b:", m["b"])

// 輸出

b: 3

初始化時也可以不指定鍵和值,這種情況和不指定容量的 make 函式是相同的。


m := map[string]int{}

等價於

m := make(map[string]int)

鍵是否存在

從初始化的 map 中獲取一個沒有儲存的鍵時,編譯器是不會報錯的,它會返回值型別的預設值。例如:值型別是 int 就返回 0、值型別是 string 就返回空字串。

那怎麼判斷鍵是否存在呢?格式如下:


v,ok := map[key]
  • v:map 的值

  • ok:bool 型別,如果 key 存在為 true,反之為 false

舉例:


// collection/map-key.go

dic := map[int]string{}

dic[0] = "a"

if v, ok := dic[0]; ok {

    fmt.Println(v)

}

// 輸出

a

刪除鍵/值對

使用 delete 函式可以刪除 map 中的鍵/值對,格式如下:


delete(map,)

注:如果鍵不存在時,編譯器也可以透過。

舉例:


m := map[string]int{

    "a": 2,

    "b": 3,

    "c": 4,

}

delete(m, "b")

fmt.Println(m)

// 輸出

map[a:2 c:4]

遍歷

遍歷 map 需要用到 for-range 語法,如果不懂先看看《流程控制》。


m := map[string]int{

    "a": 2,

    "b": 3,

    "c": 4,

}

// k 為鍵,v 為值

for k, v := range m {

    fmt.Println("key:", k, ",value:", v)

}

// 輸出

key: a ,value: 2

key: b ,value: 3

key: c ,value: 4

程式碼中 v 可以省略,這樣表示只遍歷鍵。如果只想遍歷值,那 k_ (下劃線)代替,表示省略。


// 只遍歷鍵

for k := range m {

    ...

}

// 只遍歷值

for _, v := range m {

    ...

}

引用型別

map 是引用型別,因此在傳遞過程中它只存在一份。

如果像複製 map,沒有類似 copy 的函式。實現需新建立一個 map,手動遍歷賦值。


// collection/map-copy.go

m := map[string]int{

    "a": 2,

    "b": 3,

}

// 遍歷複製

mCopy := map[string]int{}

for k, v := range m {

    mCopy[k] = v

}

總結

本篇講解了 map 的建立、遍歷、刪除等知識點,這些都很常用,所以一定要掌握。

本作品採用《CC 協議》,轉載必須註明作者和本文連結
瀟灑哥老苗

相關文章