Go語言之Map-創(chuàng)新互聯(lián)

Map是一種無序的鍵值對的集合,它主要通過Key來快速檢索數(shù)據(jù),Go語言中用它來提供哈希表的功能。

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了邯鄲免費(fèi)建站歡迎大家使用!

Map是一種數(shù)據(jù)結(jié)構(gòu),它是一個集合,用于存儲一系列無序的鍵值對。它是基于鍵存儲的,鍵就像一個索引一樣,這也是Map強(qiáng)大的地方??梢钥焖贆z索數(shù)據(jù),鍵指向與該鍵關(guān)聯(lián)的值。

內(nèi)部實(shí)現(xiàn)

Map是基于散列表來實(shí)現(xiàn)的,就是我們常說的Hash表。所以我們每次迭代Map的時候,打印的Key和Value是無序的,每次迭代的都不一樣,即使我們按照一定的順序存在也不行。

Map的散列表包含一組桶,每次存儲和查找鍵值對的時候,都要先選擇一個桶。如何選擇桶呢?就是把指定的鍵傳給散列函數(shù),就可以索引到相應(yīng)的桶了,進(jìn)而找到對應(yīng)的鍵值。

這種方式的好處在于:存儲的數(shù)據(jù)越多,索引分布越均勻,所以我們訪問鍵值對的速度也就越快。當(dāng)然存儲的細(xì)節(jié)還有很多,大家可以參考Hash相關(guān)的知識,這里我們只要記住Map存儲的是無序的鍵值對集合。

聲明和初始化

Map的創(chuàng)建有make函數(shù)、Map字面量。make函數(shù)我們用它創(chuàng)建過切片,除此之外,它還可以用來創(chuàng)建Map。

dict:=make(map[string]int)

示例中創(chuàng)建了一個鍵類型為string,值類型為int的Map。現(xiàn)在創(chuàng)建好之后,這個Map是空的,里面什么都沒有,我們給存儲一個鍵值對。

dict := make(map[string]int)
dict["張三"] = 43

存儲了一個Key為張三,Value為 43 的鍵值對數(shù)據(jù)。

此外還有一種創(chuàng)建和初始化Map的方式——使用Map字面量。對于上面的例子,我們可以同等實(shí)現(xiàn)。

dict := map[string]int{"張三":43}

使用一個大括號進(jìn)行初始化,鍵值對通過:分開,如果要同時初始化多個鍵值對,使用逗號分割。

dict := map[string]int{"張三":43,"李四":50}

當(dāng)然我們可以不指定任何鍵值對,也就是一個空Map。

dict := map[string]int{}

不管怎么樣,使用Map的字面量創(chuàng)建一定要帶上大括號。如果我們要創(chuàng)建一個nil的Map怎么做呢?nil的Map是未初始化的,所以我們可以只聲明一個變量,既不能使用Map字面量,也不能使用make函數(shù)分配內(nèi)存。

var dict map[string]int

這樣就好了,但是這樣我們是不能操作存儲鍵值對的,必須要初始化后才可以。比如使用make函數(shù),為其開啟一塊可以存儲數(shù)據(jù)的內(nèi)存,也就是初始化。

var dict map[string]int
dict = make(map[string]int)
dict["張三"] = 43
fmt.Println(dict)

Map的鍵可以是任何值,鍵的類型可以是內(nèi)置的類型,也可以是結(jié)構(gòu)類型。但是不管怎么樣,這個鍵可以使用==運(yùn)算符進(jìn)行比較,所以像切片、函數(shù)以及含有切片的結(jié)構(gòu)類型就不能用于Map的鍵了。因?yàn)樗麄兙哂幸玫恼Z義,不可比較。

對于Map的值來說,就沒有什么限制了。切片這種在鍵里不能用的,完全可以用在值里。

使用Map

Map的使用很簡單,和數(shù)組切片差不多。數(shù)組切片是使用索引,Map是通過鍵。

dict := make(map[string]int)
dict["張三"] = 43

以上示例,如果鍵張三存在,則對其值修改;如果不存在,則新增這個鍵值對。

獲取一個Map鍵的值也很簡單,和存儲差不多,還是給予上面的例子。

age := dict["張三"]

在Go Map中,如果我們獲取一個不存在的鍵的值也是可以的,返回的是值類型的零值。這樣就會導(dǎo)致我們不知道是真的存在一個零值的鍵值對呢,還是說這個鍵值對就不存在。對此,Map為我們提供了檢測一個鍵值對是否存在的方法。

age,exists := dict["李四"]

看這個例子,和獲取鍵的值沒有太大區(qū)別,只是多了一個返回值。第一個返回值是鍵的值;第二個返回值標(biāo)記這個鍵是否存在,這是一個boolean類型的變量,我們判斷它就知道該鍵是否存在了。這也是Go多值返回的好處。

如果我們想刪除一個Map中的鍵值對,可以使用Go內(nèi)置的delete函數(shù)。

delete(dict,"張三")

delete函數(shù)接受兩個參數(shù):第一個是要操作的Map,第二個是要刪除的Map的鍵。

delete函數(shù)刪除不存在的鍵也是可以的,只是沒有任何作用。

想要遍歷Map的話,可以使用for range風(fēng)格的循環(huán),和遍歷切片一樣。

dict := map[string]int{"張三": 43}
for key, value := range dict {
    fmt.Println(key, value)
}

這里的range 返回兩個值:第一個是Map的鍵,第二個是Map的鍵對應(yīng)的值。這里再次強(qiáng)調(diào),這種遍歷是無序的,也就是鍵值對不會按既定的數(shù)據(jù)出現(xiàn)。如果想按順序遍歷,可以先對Map中的鍵排序,然后遍歷排序好的鍵,把對應(yīng)的值取出來,下面看個例子就明白了。

func main() {
    dict := map[string]int{"王五": 60, "張三": 43}
    var names []string
    for name := range dict {
        names = append(names, name)
    }
    sort.Strings(names) //排序
    for _, key := range names {
        fmt.Println(key, dict[key])
    }
}

這個例子里有個技巧,range 一個Map的時候,也可以使用一個返回值,這個默認(rèn)的返回值就是Map的鍵。

在函數(shù)間傳遞Map

函數(shù)間傳遞Map是不會拷貝一個該Map的副本的,也就是說如果一個Map傳遞給一個函數(shù),該函數(shù)對這個Map做了修改,那么這個Map的所有引用,都會感知到這個修改。

func main() {
    dict := map[string]int{"王五": 60, "張三": 43}
    modify(dict)
    fmt.Println(dict["張三"])
}

func modify(dict map[string]int) {
    dict["張三"] = 10
}

上面這個例子輸出的結(jié)果是10,也就是說已經(jīng)被函數(shù)給修改了,可以證明傳遞的并不是一個Map的副本。這個特性和切片是類似的,這樣就會更高,因?yàn)閺?fù)制整個Map的代價太大了。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

標(biāo)題名稱:Go語言之Map-創(chuàng)新互聯(lián)
URL分享:http://bm7419.com/article26/didccg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開發(fā)、軟件開發(fā)域名注冊、自適應(yīng)網(wǎng)站、定制開發(fā)網(wǎng)頁設(shè)計公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)