亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Go語言之Map

發布時間:2020-06-14 15:29:33 來源:網絡 閱讀:1526 作者:baby神 欄目:編程語言

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


Map是一種數據結構,它是一個集合,用于存儲一系列無序的鍵值對。它是基于鍵存儲的,鍵就像一個索引一樣,這也是Map強大的地方。可以快速檢索數據,鍵指向與該鍵關聯的值。


內部實現


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


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


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


聲明和初始化


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


dict:=make(map[string]int)


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


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


存儲了一個Key為張三,Value為 43 的鍵值對數據。


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


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


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


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


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


dict := map[string]int{}


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


var dict map[string]int


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


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


Map的鍵可以是任何值,鍵的類型可以是內置的類型,也可以是結構類型。但是不管怎么樣,這個鍵可以使用==運算符進行比較,所以像切片、函數以及含有切片的結構類型就不能用于Map的鍵了。因為他們具有引用的語義,不可比較。


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


使用Map


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


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


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


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


age := dict["張三"]


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


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


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


如果我們想刪除一個Map中的鍵值對,可以使用Go內置的delete函數。


delete(dict,"張三")


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


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


想要遍歷Map的話,可以使用for range風格的循環,和遍歷切片一樣。


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


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


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的時候,也可以使用一個返回值,這個默認的返回值就是Map的鍵。


在函數間傳遞Map


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


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

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


上面這個例子輸出的結果是10也就是說已經被函數給修改了,可以證明傳遞的并不是一個Map的副本。這個特性和切片是類似的,這樣就會更高,因為復制整個Map的代價太大了。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

扎囊县| 奉节县| 林西县| 保康县| 大邑县| 黄冈市| 当阳市| 莆田市| 如皋市| 阜城县| 防城港市| 高平市| 万山特区| 公主岭市| 乌鲁木齐市| 肇庆市| 柯坪县| 上虞市| 会东县| 贵南县| 九台市| 翼城县| 林甸县| 阳高县| 南开区| 河曲县| 麻阳| 仲巴县| 安顺市| 西畴县| 大足县| 宁海县| 西乌珠穆沁旗| 大悟县| 怀来县| 时尚| 临武县| 长岛县| 莫力| 微山县| 杭锦旗|