国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

go基礎(chǔ)07-了解map實(shí)現(xiàn)原理并高效使用

這篇具有很好參考價(jià)值的文章主要介紹了go基礎(chǔ)07-了解map實(shí)現(xiàn)原理并高效使用。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

對(duì)于C程序員出身的Gopher來說,map類型是和切片、interface一樣能讓他們感受到Go語言先進(jìn)性的重要語法元素。map類型也是Go語言中最常用的數(shù)據(jù)類型之一。

go 中 map 怎么表現(xiàn)?

一些有關(guān)Go語言的中文教程或譯本將map稱為字典或哈希表,但在這里我選擇不譯,直接使用map。map是Go語言提供的一種抽象數(shù)據(jù)類型,它表示一組無序的鍵值對(duì)(key-value,后續(xù)我們會(huì)直接使用key和value分別表示鍵和值)。

map類型不支持“零值可用”,未顯式賦初值的map類型變量的零值為nil。對(duì)處于零值狀態(tài)的map變量進(jìn)行操作將會(huì)導(dǎo)致運(yùn)行時(shí)panic:

var m map[string]int // m = nil
m["key"] = 1 // panic: assignment to entry in nil map

簡(jiǎn)單來說就是不能不賦值,只對(duì)key 賦值是不行的。

我們必須對(duì)map類型變量進(jìn)行顯式初始化后才能使用它。
和切片一樣,創(chuàng)建map類型變量有兩種方式:

  • 一種是使用復(fù)合字面值,
1)使用復(fù)合字面值創(chuàng)建map類型變量
// $GOROOT/src/net/status.go
var statusText = map[int]string{
StatusOK: "OK",
StatusCreated: "Created",
StatusAccepted: "Accepted",
...
}
  • 一種是使用make這個(gè)預(yù)聲明的內(nèi)置函數(shù)。
2)使用make創(chuàng)建map類型變量
// $GOROOT/src/net/client.go
icookies = make(map[string][]*Cookie)
// $GOROOT/src/net/h2_bundle.go
http2commonLowerHeader = make(map[string]string, len(common))

和切片一樣,map也是引用類型,將map類型變量作為函數(shù)參數(shù)傳入不會(huì)有很大的性能損耗,并且在函數(shù)內(nèi)部對(duì)map變量的修改在函數(shù)外部也是可見的,比如下面的例子:

func foo(m map[string]int) {
	m["key1"] = 11
	m["key2"] = 12
}
func main() {
m := map[string]int{
	"key1": 1,
	"key2": 2,
}
 fmt.Println(m) // map[key1:1 key2:2]
foo(m)
fmt.Println(m) // map[key1:11 key2:12]
}

map的基本操作

1. 插入數(shù)據(jù)

面對(duì)一個(gè)非nil的map類型變量,我們可以向其中插入符合map類型定義的任意鍵值對(duì)。
Go運(yùn)行時(shí)會(huì)負(fù)責(zé)map內(nèi)部的內(nèi)存管理,因此除非是系統(tǒng)內(nèi)存耗盡,我們不用擔(dān)心向map中插入數(shù)據(jù)的數(shù)量。

m := make(map[K]V)
m[k1] = v1
m[k2] = v2
m[k3] = v3

如果key已經(jīng)存在于map中,則該插入操作會(huì)用新值覆蓋舊值:

m := map[string]int {
"key1" : 1,
"key2" : 2,
}
m["key1"] = 11 // 11會(huì)覆蓋掉舊值1
m["key3"] = 3 // map[key1:11 key2:2 key3:3]

2. 獲取數(shù)據(jù)個(gè)數(shù)

和切片一樣,map也可以通過內(nèi)置函數(shù)len獲取當(dāng)前已經(jīng)存儲(chǔ)的數(shù)據(jù)個(gè)數(shù):

m := map[string]int {
"key1" : 1,
"key2" : 2,
}
fmt.Println(len(m)) // 2
m["key3"] = 3
fmt.Println(len(m)) // 3

3. 查找和數(shù)據(jù)讀取

map類型更多用在查找和數(shù)據(jù)讀取場(chǎng)合。所謂查找就是判斷某個(gè)key是否存在于某個(gè)map
中。我們可以使用“comma ok”慣用法來進(jìn)行查找

_, ok := m["key"]
if !ok {
// "key"不在map中
}

這里我們并不關(guān)心某個(gè)key對(duì)應(yīng)的value,而僅僅關(guān)心某個(gè)key是否在map中,因此我們
使用空標(biāo)識(shí)符(blank identifier)忽略了可能返回的數(shù)據(jù)值,而僅關(guān)心ok的值是否為
true(表示在map中)。

如果要讀取key對(duì)應(yīng)的value的值,我們可能會(huì)寫出下面這樣的代碼:

m := map[string]int
m["key1"] = 1
m["key2"] = 2
v := m["key1"]
fmt.Println(v) // 1
v = m["key3"]
fmt.Println(v) // 0

上面的代碼在key存在于map中(如“key1”)的情況下是沒有問題的。但是如果key不
存在于map中(如“key3”),我們看到v仍然被賦予了一個(gè)“合法”值0,這個(gè)值是value
類型int的零值。在這樣的情況下,我們無法判定這個(gè)0是“key3”對(duì)應(yīng)的值還是
因“key3”不存在而返回的零值。為此我們還需要借助“comma ok”慣用法

m := map[string]int
v, ok := m["key"]
if !ok {
// "key"不在map中
}
fmt.Println(v)

我們需要通過ok的值來判定key是否存在于map中。只有當(dāng)ok = true時(shí),所獲得的
value值才是我們所需要的。綜上,Go語言的一個(gè)最佳實(shí)踐是總是使用“comma ok”慣用法讀取map中的值。

4. 刪除數(shù)據(jù)

我們借助內(nèi)置函數(shù)delete從map中刪除數(shù)據(jù):

m := map[string]int {
"key1" : 1,
"key2" : 2,
}
fmt.Println(m) // map[key1:1 key2:2]
delete(m, "key2")
fmt.Println(m) // map[key1:1]

注意,即便要?jiǎng)h除的數(shù)據(jù)在map中不存在,delete也不會(huì)導(dǎo)致panic。

5. 遍歷數(shù)據(jù)

我們可以像對(duì)待切片那樣通過for range語句對(duì)map中的數(shù)據(jù)進(jìn)行遍歷:

func main() {
m := map[int]int{
1: 11,
 2: 12,
3: 13,
}
fmt.Printf("{ ")
for k, v := range m {
fmt.Printf("[%d, %d] ", k, v)
}
fmt.Printf("}\n")
}

我們看到對(duì)同一map做多次遍歷,遍歷的元素次序并不相同。這是因?yàn)镚o運(yùn)行時(shí)在初始
化map迭代器時(shí)對(duì)起始位置做了隨機(jī)處理。因此千萬不要依賴遍歷map所得到的元素次序。

如果你需要一個(gè)穩(wěn)定的遍歷次序,那么一個(gè)比較通用的做法是使用另一種數(shù)據(jù)結(jié)構(gòu)來
按需要的次序保存key,比如切片:
文章來源地址http://www.zghlxwxcb.cn/news/detail-704954.html

import "fmt"
func doIteration(sl []int, m map[int]int) {
fmt.Printf("{ ")
for _, k := range sl { // 按切片中的元素次序迭代
v, ok := m[k]
if !ok {
continue
}
fmt.Printf("[%d, %d] ", k, v)
}
fmt.Printf("}\n")
}
func main() {
var sl []int
m := map[int]int{
1: 11,
2: 12,
3: 13,
}
for k, _ := range m {
sl = append(sl, k) // 將元素按初始次序保存在切片中
}
for i := 0; i < 3; i++ {
doIteration(sl, m)
}
}
$go run map_stable_iterate.go
{ [1, 11] [2, 12] [3, 13] }
{ [1, 11] [2, 12] [3, 13] }
{ [1, 11] [2, 12] [3, 13] }

到了這里,關(guān)于go基礎(chǔ)07-了解map實(shí)現(xiàn)原理并高效使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 編程筆記 Golang基礎(chǔ) 007 第一個(gè)程序:hello world 使用Goland

    編程筆記 Golang基礎(chǔ) 007 第一個(gè)程序:hello world 使用Goland

    開始在Goland環(huán)境中編程go語言代碼啦。 打開GoLand軟件。 選擇 “File”(文件)菜單,然后點(diǎn)擊 “New Project”(新建項(xiàng)目)或使用快捷鍵 Ctrl+Shift+A 并搜索 “New Project”。 在新建項(xiàng)目向?qū)е?,選擇 “Go” 并點(diǎn)擊 “Next” 按鈕。 配置項(xiàng)目設(shè)置: 為項(xiàng)目選擇一個(gè)合適的保存位置。

    2024年02月20日
    瀏覽(24)
  • goland setup go env

    goland setup go env

    go env -w設(shè)置的變量,在goland中不生效,需要額外配置。 點(diǎn)擊goland-preference,在go module里,設(shè)置go環(huán)境變量即可。

    2024年02月08日
    瀏覽(22)
  • 小白學(xué)go基礎(chǔ)03-了解Go項(xiàng)目的項(xiàng)目結(jié)構(gòu)

    小白學(xué)go基礎(chǔ)03-了解Go項(xiàng)目的項(xiàng)目結(jié)構(gòu)

    我們先來看看第一個(gè)Go項(xiàng)目——Go語言自身——的項(xiàng)目結(jié)構(gòu)是什么樣的。Go項(xiàng)目的項(xiàng)目結(jié)構(gòu)自1.0版本發(fā)布以來一直十分穩(wěn)定,直到現(xiàn)在Go項(xiàng)目的頂層結(jié)構(gòu)基本沒有大的改變。 截至Go項(xiàng)目commit 1e3ffb0c(2019.5.14), Go1.0 項(xiàng)目結(jié)構(gòu)如下: 作為Go語言的創(chuàng)世項(xiàng)目,Go的項(xiàng)目結(jié)構(gòu)的布局對(duì)

    2024年02月09日
    瀏覽(48)
  • go基礎(chǔ)10 -字符串的高效構(gòu)造與轉(zhuǎn)換

    前面提到過,Go原生支持通過+/+=操作符來連接多個(gè)字符串以構(gòu)造一個(gè)更長(zhǎng)的字符串,并且通過+/+=操作符的字符串連接構(gòu)造是最自然、開發(fā)體驗(yàn)最好的一種。 但Go還提供了其他一些構(gòu)造字符串的方法,比如: ● 使用fmt.Sprintf; ● 使用strings.Join; ● 使用strings.Builder; ● 使用

    2024年02月09日
    瀏覽(23)
  • 【Go】Goland下載與安裝教程(詳細(xì))

    【Go】Goland下載與安裝教程(詳細(xì))

    一、GoLand官網(wǎng)下載安裝 開發(fā)環(huán)境:https://www.jetbrains.com/go/ 軟件激活ToolBox: 一鍵Activate,激活后出現(xiàn)success,開發(fā)工具即可直接使用: 二、下載go語言sdk(go的標(biāo)準(zhǔn)庫) 下載地址:https://golang.google.cn/dl/ 三、創(chuàng)建工程目錄 創(chuàng)建一個(gè)工程目錄,如 D:SoftwaresGOGoWorkstation ,這個(gè)目錄

    2024年02月04日
    瀏覽(30)
  • 新手小白需要了解的 Go 基礎(chǔ)細(xì)節(jié)雜談

    新手小白需要了解的 Go 基礎(chǔ)細(xì)節(jié)雜談

    Golang 基礎(chǔ)知識(shí)一遍過 ?? 今日記錄一下 學(xué)習(xí) golang 這門語言遇到的一些比較特殊的細(xì)節(jié),供大家參考。 ? ? ? ?所以,在我們輸出內(nèi)容的時(shí)候,可以包含很多的非 ASCII 碼字符。實(shí)際上,Go 是天生支持 UTF-8 的,任何字符都可以直接輸出,甚至可以使用 UTF-8 中的任何字符作為標(biāo)

    2023年04月09日
    瀏覽(22)
  • MacOS goland go1.21 debug問題

    MacOS goland go1.21 debug問題

    brew install dlv 安裝之后在終端會(huì)顯示所在目錄 類似/usr/local/Cellar/delve/1.21.0/bin 在文件系統(tǒng)中找到goland 右擊選擇show package contents - Contents - plugins - go 嘗試替換 其中對(duì)應(yīng)系統(tǒng) 的 dlv 結(jié)果還是不行 然后打開應(yīng)用goland Help → Edit Custom Properties 增加以下代碼: dlv.path=/usr/local/Cellar/del

    2024年02月11日
    瀏覽(25)
  • C++進(jìn)階--使用哈希表實(shí)現(xiàn)unordered_map和unordered_set的原理與實(shí)例

    C++進(jìn)階--使用哈希表實(shí)現(xiàn)unordered_map和unordered_set的原理與實(shí)例

    本文將介紹如何使用哈希表來實(shí)現(xiàn)C++ STL庫中的unordered_map和unordered_set容器。我們將會(huì)解釋哈希表的基本原理,并給出具體的代碼示例,幫助讀者更好地理解和應(yīng)用哈希表。 哈希原理講解–鏈接入口 set和map的實(shí)現(xiàn)的文章,與unordered_map實(shí)現(xiàn)類似 unordered_set是一種集合存儲(chǔ)的容器

    2024年04月09日
    瀏覽(22)
  • Go語言集成開發(fā)環(huán)境(IDE):GoLand 2023中文

    Go語言集成開發(fā)環(huán)境(IDE):GoLand 2023中文

    GoLand 2023是一款由JetBrains開發(fā)的現(xiàn)代化、功能豐富的Go語言集成開發(fā)環(huán)境(IDE) 。它提供了智能代碼提示和自動(dòng)完成、強(qiáng)大的內(nèi)置調(diào)試器以及代碼重構(gòu)工具,幫助開發(fā)者提高編碼效率并確保代碼質(zhì)量。GoLand 2023還支持多種版本控制系統(tǒng),集成了測(cè)試工具,并提供了代碼審查功能

    2024年02月06日
    瀏覽(25)
  • 【Go進(jìn)階】怎么實(shí)現(xiàn)并發(fā)安全的map

    【Go進(jìn)階】怎么實(shí)現(xiàn)并發(fā)安全的map

    go語言提供的數(shù)據(jù)類型中,只有channel是并發(fā)安全的,基礎(chǔ)map并不是并發(fā)安全的。以下三種方案實(shí)現(xiàn)了并發(fā)安全的map。 實(shí)現(xiàn)原理: 給map添加一把讀寫鎖,讀操作加讀鎖進(jìn)行讀?。惶砑?,更新,刪除,遍歷,獲取長(zhǎng)度這些操作加寫鎖后在進(jìn)行操作。 代碼實(shí)現(xiàn): 以下代碼是并發(fā)

    2024年02月03日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包