map

在其他語言諸如C++/Java中, map一般都以庫的方式提供 如C++中的 std::map<> ,Java中的Hashmap<>,在golang中map為內(nèi)置類型,不需要引用任何庫.

map是一堆未排序鍵值對的集合,map的key必須為可比較類型,比如 ==!=,map查找比線性查找快,但慢于索引查找(數(shù)組,切片)

定義一個(gè)map

格式 var name map[keytype]valuetype

其中的keytype為map中鍵的類型,valuetype為map中值的類型,map還可以使用 := 或者 make()創(chuàng)建,如:

var a map[int]int
var b = map[string]string{}
c := map[string]bool{}
d := make(map[string]int)

map的初始化

map類似于數(shù)組和切片,可以在定義時(shí)直接指定初始值 如:

var a = map[string]string{"name": "zhangsan", "age": "16", "sex": "男"}

map元素訪問

上邊定義并初始化了一個(gè)map,那么如何訪問一個(gè)map中的元素呢?

可以通過鍵(key)來訪問指定的value 如:

var a = map[string]string{"name": "zhangsan", "age": "16", "sex": "男"}
fmt.Println(a["name"],a["age"])

上述程序?qū)⑤敵? zhangsan 16

將上述的代碼修改一下

var a = map[string]string{"name": "zhangsan", "age": "16", "sex": "男"}
fmt.Println(a["name"], a["age"], a["parent"])

map中并沒有parent這個(gè)鍵,在諸如C++/Java或其他語言中,如果訪問一個(gè)并不存在的鍵,將直接導(dǎo)致程序異常,所以判斷一個(gè)map中是否存在某個(gè)鍵,就成了必需的步驟,但在golang中,這些都不是問題

上述代碼不會(huì)發(fā)生任何異?;蛘弋a(chǎn)生警告
在golang中 如果訪問一個(gè)未定義的key 將返回這個(gè)map中value的默認(rèn)值,來驗(yàn)證一下

package main

import (
    "fmt"
)

func main() {
    var a = map[string]string{"name": "zhangsan", "age": "16", "sex": "男"}
    fmt.Println(a["parent"])
    if a["parent"] == "" {
        fmt.Println("yes")
    }

    var b = map[int]int{1: 1, 2: 2}
    fmt.Println(b[3])
    if b[3] == 0 {
        fmt.Println("yes")
    }
}

上述程序?qū)⑤敵?br> //這個(gè)是空字符串
yes
0
yes

但顯然我們并不想要這個(gè)結(jié)果,golang中提供了一種方式來判斷數(shù)組中是否含有某個(gè)鍵

格式 value,bool := map[key] 如下列程序

func main() {
    var a = map[string]string{"name": "zhangsan", "age": "16", "sex": "男"}
    if value, ok := a["parent"]; ok == true {
        fmt.Println(value)
    } else {
        fmt.Println("key not in map")
    }
}

注意:golang中過的if語句中定義的變量在語句塊外是訪問不到的

修改map中的元素

和數(shù)組一樣,可以使用key來修改map中的元素

var a = map[string]string{"name": "zhangsan", "age": "16", "sex": "男"}
fmt.Println(a)
a["name"] = "李四"
fmt.Println(a)

上述代碼將輸出
map[name:zhangsan age:16 sex:男]
map[name:李四 age:16 sex:男]

新增元素

與slice不同,map元素的新增不需要使用copy()函數(shù) 可以直接 map[key] = value 的方式增加元素 如:

package main

import (
    "fmt"
)

func main() {
    var a = map[string]string{"name": "zhangsan", "age": "16", "sex": "男"}
    a["girlfriend"] = "蒼老師"
    fmt.Println(a)
}

刪除元素

比slice相比,map提供delete()函數(shù)進(jìn)行元素的刪除
格式 delete(map,key) 如下例:

package main

import (
    "fmt"
)

func main() {
    var a = map[string]string{"name": "zhangsan", "age": "16", "sex": "男"}
    delete(a, "name")
    fmt.Println(a)
}

以上程序?qū)ap[age:16 sex:男]

map是引用類型

map是引用類型,來看一個(gè)簡單的例子

func main() {
    var a = map[int]int{1: 1, 2: 2}
    b := a
    a[1] = 123456
    fmt.Println(a, b)
}

以上程序會(huì)輸出 map[1:123456 2:2] map[1:123456 2:2]

我們再傳遞進(jìn)函數(shù)里面測試下,關(guān)于函數(shù)的定義后面我們會(huì)講,此處只是一個(gè)demo

func main() {
    var a = map[int]int{1: 1, 2: 2}
    b := a
    test(a)
    fmt.Println(a, b)
}

func test(a map[int]int) {
    a[1] = 111
}

以上程序會(huì)輸出 map[2:2 1:111] map[1:111 2:2] 或者 map[1:111 2:2] map[1:111 2:2]

為什么呢?仔細(xì)思考一下,這是否再一次說明了map是無序的呢?

map的遍歷

與數(shù)組類似 map也可以使用 for range關(guān)鍵字來進(jìn)行遍歷

var a = map[string]string{"name": "zhangsan", "age": "16", "sex": "男"}
for key, value := range a {
    fmt.Println(key, value)
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容