天天看點

go語言之map深度了解

Map存儲的是無序的鍵值對集合

//建立map
m := make(map[keyType]valueType)
一,初始化map
month := make(map[string]int)
month["January"] = 1
month["February"] = 2
month["March"] = 3
           

------------------------------------------------- map 初始化 ---------------------------------------

map
month := map[string]int{"January":1,"February":2,"March":3}
month := map[string]int{
 "January":1,
 "February":2,
 "March":3,
}
           

------------------------------------------- 建立空map -------------------------------------------

month := map[string]int{}
fmt.Println(month)        // 輸出:map[]
//對于nil的map是不能存取鍵值對的,
//否則就會報錯panic: assignment to entry in nil map
//可以使用提到的make函數,為其初始化:
var month map[string]int
month = make(map[string]int)
month["January"] = 1
fmt.Println(month)   // 輸出:map[January:1]
           

------------------------------------------ map key --------------------------------------------

Map的零值就是nil,Map就是底層Hash表的引用。

Map的key可以是内置類型,也可以是結構類型,隻要可以使用 == 運算符做比較,都可以作為key

切片、函數以及包含切片的結構類型,這些類型由于具有引用語義,不能作為key,使用這些類型會造成編譯錯誤:

month := map[[]string]int{}
// 編譯錯誤:invalid map key type []string
           

---------------------------------------------- map value ------------------------------------------

Map的value,沒有類型限制,當然也沒有任何理由阻止使用者使用切片作為Map的值:

m := map[string][]int{}
slice := []int{1,2,3}
m["slice"] = slice
fmt.Println(m["slice"])
// 或者
slice := []int{1,2,3}
m := map[string][]int{"slice":slice}
fmt.Println(m["slice"])
           

---------------------------------------------- map update ---------------------------------------

Map的使用就很簡單了,類似于數組,數組是使用索引,Map使用key擷取或修改value

m := map[string]int{}
m["January"] = 1         // 指派
fmt.Println(m)     // 輸出:map[January:1]
m["January"] = 10       //修改
fmt.Println(m)              // 輸出:map[January:10]
january := m["January"]   // 擷取value
fmt.Println(january)      // 輸出:10
//執行修改操作的時候,如果key已經存在,則新值會覆寫舊值,key是不允許重複的
           

----------------------------------------- map check --------------------------------------------

擷取一個不存在的key的value的時候,會傳回值類型對應的零值,

是存在一個值為零值的鍵值對 還是鍵值對就根本不存在 ?

february,exists := m["February"]
fmt.Println(february,exists)   // 輸出:0 false
           

擷取值的時候多了一個傳回值,第一個傳回值是value,第二個傳回值是boolean類型變量,表示value是否存在。判斷一個key是否存在就提供了很大便利

------------------------------------------ map delete ---------------------------------------------

函數原型

//第一個參數是Map,第二個參數是key。
func delete(m map[Type]Type1, key Type) 
           
m := map[string]int{
 "January":1,
 "February":2,
 "March":3,
}
fmt.Println(m)     // 輸出:map[March:3 January:1 February:2]
delete(m,"January")
fmt.Println(m)     // 輸出:map[February:2 March:3]
//删除一個不存在的鍵值對時,delete函數不會報錯,沒任何作用。
           

-------------------------------------- map range -------------------------------------------------

Map沒法使用for循環周遊,跟數組、切片一樣,可以使用range周遊。

for key, value := range m {
 fmt.Println(key, "=>", value)
}
//輸出 map周遊是無序的
February => 2
March => 3
January => 1
           

-------------------------------------------- map 内置函數 ----------------------------------------

//len函數傳回Map中鍵值對的數量
fmt.Println("len(m) =",len(m))   
           

------------------------------------ map 直接指派是 引用 ------------------------------------

Map是對底層資料的引用 編寫代碼的過程中,會涉及到Map拷貝、函數間傳遞Map等。

跟Slice類似,Map指向的底層資料是不會發生copy的。

m := map[string]int{
 "January":1,
 "February":2,
 "March":3,
}
month := m    
delete(month,"February")
fmt.Println(m)
fmt.Println(month)
//輸出
map[January:1 March:3]
map[January:1 March:3]
//将Map m指派給month,删除了month中的一個鍵值對,m也發生了改變,
//說明Map拷貝時,m和month是共享底層資料的,改變其中一方資料,
//另一方也會随之改變,即是引用。
-----------
           

--------------------------------------------- map 實作拷貝 ---------------------------------------

month := map[string]int{}

m := map[string]int{
 "January":1,
 "February":2,
 "March":3,
}

for key,value := range m{
 month[key] = value
}

delete(month,"February")
fmt.Println(m)
fmt.Println(month)
//輸出

map[January:1 February:2 March:3]
map[January:1 March:3]