欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語言學(xué)習(xí)之映射(map)的用法詳解

 更新時(shí)間:2022年04月21日 16:17:27   作者:隱姓埋名4869  
Map是一種無序的鍵值對(duì)的集合。這篇文章主要為大家詳細(xì)介紹了Go語言中映射的用法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Go語言有一定的幫助,需要的可以參考一下

1. 什么是 map

Map 是一種無序的鍵值對(duì)的集合。Map 最重要的一點(diǎn)是通過 key 來快速檢索數(shù)據(jù),key 類似于索引,指向數(shù)據(jù)的值

Map 是無序的,我們無法決定它的返回順序,這是因?yàn)?Map 是使用 hash 表來實(shí)現(xiàn)的

Map 是引用類型,必須初始化才能使用。其中,key的類型除了切片等引用類型,其他類型都可以;而value則可使用所有類型的值

2. 創(chuàng)建 map

可以通過make()創(chuàng)建map,它會(huì)先創(chuàng)建好底層數(shù)據(jù)結(jié)構(gòu),然后再創(chuàng)建map,并讓map指向底層數(shù)據(jù)結(jié)構(gòu)

my_map := make(map[string]int)

[string]表示map的key的數(shù)據(jù)類型

int表示key對(duì)應(yīng)的值

直接通過大括號(hào)創(chuàng)建并初始化賦值:

// 空map
my_map := map[string]string{}
 
// 初始化賦值
my_map := map[string]string{"Red": "#da1337","Orange": '#e95a22"}
 
// 格式化賦值
my_map := map[string]int{
"Java":11,
"Perl":8,
"Python":13, // 注意結(jié)尾的逗號(hào)不能少
}

注意:

其中map的key可以是任意內(nèi)置的數(shù)據(jù)類型(如int),或者其它可以通過 == 進(jìn)行等值比較的數(shù)據(jù)類型,如interface和指針可以,slice、數(shù)組、map、struct類型都不能作為key ,并且key必須唯一。

但value基本可以是任意類型,例如嵌套一個(gè)slice到map中:

my_map := map[string][]int{}

3. 訪問 map

訪問map中的元素時(shí),指定它的key即可,注意string類型的key必須加上引號(hào):

package main
 
import "fmt"
 
func main() {
    my_map := map[string]int{
        "1": 10,
        "2": 20,
        "3": 30,
        "4": 40,
    }
 
    //訪問
    fmt.Println(my_map["1"])
    fmt.Println(my_map)
 
    fmt.Println("")
 
    //賦值已有的key & value
    my_map["2"] = 50
    fmt.Println(my_map["2"])
    fmt.Println(my_map)
 
    fmt.Println("")
 
    //賦值新的key&value
    my_map["5"] = 66
    fmt.Println(my_map["5"])
    fmt.Println(my_map)
}

輸出結(jié)果

10
map[1:10 2:20 3:30 4:40]
50
map[1:10 2:50 3:30 4:40]
66
map[1:10 2:50 3:30 4:40 5:66]

4. nil map和空map

空map是不做任何賦值的map:

// 空map
package main
 
import "fmt"
 
func main() {
    my_map := map[string]string{}
 
    fmt.Println(my_map)
}

輸出結(jié)果

map[]

nil map,它將不會(huì)做任何初始化,不會(huì)指向任何數(shù)據(jù)結(jié)構(gòu):

// nil map
var my_map map[string]string

nil map和empty map的關(guān)系,就像nil slice和empty slice一樣,兩者都是空對(duì)象,未存儲(chǔ)任何數(shù)據(jù),但前者不指向底層數(shù)據(jù)結(jié)構(gòu),后者指向底層數(shù)據(jù)結(jié)構(gòu),只不過指向的底層對(duì)象是空對(duì)象。

使用println輸出看下即可知道:

package main
 
func main() {
    var nil_map map[string]string
    println(nil_map)
 
    emp_map := map[string]string{}
    println(emp_map)
}

輸出結(jié)果:

0x0
0xc04204de38

所以,map類型實(shí)際上就是一個(gè)指針。

5. map中元素的返回值

當(dāng)訪問map中某個(gè)元素的時(shí)候,有兩種返回值的格式:

value := my_map["key"]
value,exists := my_map["key"]

第一種很好理解,就是檢索map中key對(duì)應(yīng)的value值。如果key不存在,則value返回值對(duì)應(yīng)數(shù)據(jù)類型的0。例如int為數(shù)值0,布爾為false,字符串為空""。

第二種不僅返回key對(duì)應(yīng)的值,還根據(jù)key是否存在返回一個(gè)布爾值賦值給exists變量。所以,當(dāng)key存在時(shí),value為對(duì)應(yīng)的值,exists為true;當(dāng)key不存在,value為0(同樣是各數(shù)據(jù)類型所代表的0),exists為false。

看下例子:

package main
 
import "fmt"
 
func main() {
    my_map := map[string]int{
        "1": 10,
        "2": 20,
        "3": 30,
        "4": 40,
    }
    a := my_map["1"]
    b, exists1 := my_map["2"]
    c, exists2 := my_map["5"]
    fmt.Println(a)
    fmt.Println(b, exists1)
    fmt.Println(c, exists2)
}

上面將輸出如下結(jié)果:

10
20 true
0 false

在Go中設(shè)置類似于這種多個(gè)返回值的情況很多,即便是自己編寫函數(shù)也會(huì)經(jīng)常設(shè)置它的exists屬性。

6. len()和delete()

len()函數(shù)用于獲取map中元素的個(gè)數(shù),即有多個(gè)少key。delete()用于刪除map中的某個(gè)key。

package main
 
import "fmt"
 
func main() {
    my_map := map[string]int{
        "1": 10,
        "2": 20,
        "3": 30,
        "4": 40,
    }
 
    fmt.Printf("刪除前長(zhǎng)度為%d\n", len(my_map))
    delete(my_map, "1")
    fmt.Printf("刪除后長(zhǎng)度為%d", len(my_map))
}

輸出結(jié)果如下

刪除前長(zhǎng)度為4
刪除后長(zhǎng)度為3

7. 測(cè)試map中元素是否存在

兩種方式可以測(cè)試map中是否存在某個(gè)key:

① 根據(jù)map元素的第二個(gè)返回值來判斷

② 根據(jù)返回的value是否為0(不同數(shù)據(jù)類型的0不同)來判斷

方式一:直接訪問map中的該元素,將其賦值給兩個(gè)變量,第二個(gè)變量就是元素是否存在的修飾變量。

package main
 
import "fmt"
 
func main() {
    my_map := map[string]int{
        "1": 10,
        "2": 20,
        "3": 30,
        "4": 40,
    }
     
//方法1
/* value, exists := my_map["1"]
    if exists {
        fmt.Println("存在", value)
    }
 */
 
 
    //方法2
    if value, exists := my_map["1"]; exists {
        fmt.Printf("值存在, value=%d", value)
    }
}

輸出結(jié)果如下

值存在, value=10

方式二:根據(jù)map元素返回的value判斷。因?yàn)樵搈ap中的value部分是int類型,所以它的0是數(shù)值的0。

package main
 
import "fmt"
 
func main() {
    my_map := map[string]int{
        "1": 10,
        "2": 20,
        "3": 30,
        "4": 40,
    }
 
    value := my_map["5"]
    if value == 0 {
        fmt.Println("不存在")
    }
}

輸出結(jié)果如下

不存在

如果map的value數(shù)據(jù)類型是string,則判斷是否為空:

package main
 
import "fmt"
 
func main() {
    my_map := map[string]string{
        "1": "book",
        "2": "games",
        "3": "computer",
    }
 
    value := my_map["5"]
    if value == "" {
        fmt.Println("不存在")
    }
}

輸出結(jié)果如下

不存在

由于map中的value有可能本身是存在的,但它的值為0,這時(shí)就會(huì)出現(xiàn)誤判斷。例如下面的"3",它已經(jīng)存在,但它對(duì)應(yīng)的值為0

package main
 
import "fmt"
 
func main() {
    my_map := map[string]int{
        "1": 22,
        "2": 11,
        "3": 0,
    }
 
    value := my_map["3"]
    if value == 0 {
        fmt.Println("不存在")
    }
}

輸出結(jié)果如下

不存在

所以,應(yīng)當(dāng)使用第一種方式進(jìn)行判斷元素是否存在。

8. 迭代遍歷 map

因?yàn)閙ap是key/value類型的數(shù)據(jù)結(jié)構(gòu),key就是map的index,所以range關(guān)鍵字對(duì)map操作時(shí),將返回key和value。

package main
 
import "fmt"
 
func main() {
    my_map := map[string]int{
        "1": 22,
        "2": 11,
        "3": 0,
        "4": 55,
        "5": 66,
    }
 
    for k, v := range my_map {
        fmt.Printf("key=%s, value=%d\n", k, v)
    }
}

輸出結(jié)果如下

key=1, value=22
key=2, value=11
key=3, value=0
key=4, value=55
key=5, value=66

如果range迭代map時(shí),只給一個(gè)返回值,則表示迭代map的key:

package main
 
import "fmt"
 
func main() {
    my_map := map[string]int{
        "1": 22,
        "2": 11,
        "3": 0,
        "4": 55,
        "5": 66,
    }
 
    for key := range my_map {
        fmt.Println("key=", key)
    }
}

輸出結(jié)果

key= 1
key= 2
key= 3
key= 4
key= 5

9. 獲取map中所有的key

Go中沒有提供直接獲取map所有key的函數(shù)。所以,只能自己寫,方式很簡(jiǎn)單,range遍歷map,將遍歷到的key放進(jìn)一個(gè)slice中保存起來。

package main
 
import "fmt"
 
func main() {
    my_map := map[string]int{
        "Java":   11,
        "Perl":   8,
        "Python": 13,
        "Shell":  23,
    }
 
    // 保存map中key的slice
    // slice類型要和map的key類型一致
    keys := make([]string,0,len(my_map))
 
    // 將map中的key遍歷到keys中
    for map_key,_ := range my_map {
        keys = append(keys,map_key)
    }
 
    fmt.Println(keys)
}

注意上面聲明的slice中要限制長(zhǎng)度為0,否則聲明為長(zhǎng)度4、容量4的slice,而這4個(gè)元素都是空值,而且后面append()會(huì)直接對(duì)slice進(jìn)行一次擴(kuò)容,導(dǎo)致append()后的slice長(zhǎng)度為map長(zhǎng)度的2倍,前一半為空,后一般才是map中的key。

10. 傳遞map給函數(shù)

map是一種指針,所以將map傳遞給函數(shù),僅僅只是復(fù)制這個(gè)指針,所以函數(shù)內(nèi)部對(duì)map的操作會(huì)直接修改外部的map。

例如,test()用于給map的key對(duì)應(yīng)的值加1。

package main
 
import "fmt"
 
func main() {
    my_map := map[string]int{
        "1": 22,
        "2": 11,
        "3": 0,
        "4": 55,
        "5": 66,
    }
    fmt.Println("修改之前key=", my_map["3"])
    fmt.Println(my_map)
 
    fmt.Println("")
 
    test(my_map, "3")
    fmt.Println("修改之后key=", my_map["3"])
    fmt.Println(my_map)
 
}
 
func test(m map[string]int, key string) {
    m[key] += 1
}

輸出結(jié)果如下

修改之前key= 0
map[1:22 2:11 3:0 4:55 5:66]
 
修改之后key= 1
map[1:22 2:11 3:1 4:55 5:66]

到此這篇關(guān)于Go語言學(xué)習(xí)之映射(map)的用法詳解的文章就介紹到這了,更多相關(guān)Go語言映射內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • go內(nèi)置函數(shù)copy()的具體使用

    go內(nèi)置函數(shù)copy()的具體使用

    當(dāng)我們?cè)贕o語言中需要將一個(gè)切片的內(nèi)容復(fù)制到另一個(gè)切片時(shí),可以使用內(nèi)置的copy()函數(shù),本文就介紹了go內(nèi)置函數(shù)copy()的具體使用,感興趣的可以了解一下
    2023-08-08
  • 詳解如何在golang項(xiàng)目開發(fā)中創(chuàng)建自己的Module

    詳解如何在golang項(xiàng)目開發(fā)中創(chuàng)建自己的Module

    既然我們使用了很多開源的 module為我們的日常開發(fā)提供了很多的便捷性,那我們?cè)撊绾螌?shí)現(xiàn)自己的 module 來提供給團(tuán)隊(duì)中使用,接下小編就給大家介紹一下在golang項(xiàng)目開發(fā)如何創(chuàng)建自己的Module,需要的朋友可以參考下
    2023-09-09
  • Golang使用Docker進(jìn)行集成測(cè)試的示例詳解

    Golang使用Docker進(jìn)行集成測(cè)試的示例詳解

    集成測(cè)試需要解決外部依賴問題,如?MySQL、Redis、網(wǎng)絡(luò)等依賴,本文就來聊聊?Go?程序如何使用?Docker?來解決集成測(cè)試中外部依賴問題吧
    2023-07-07
  • Golang?Compare?And?Swap算法詳細(xì)介紹

    Golang?Compare?And?Swap算法詳細(xì)介紹

    CAS算法是一種有名的無鎖算法。無鎖編程,即不使用鎖的情況下實(shí)現(xiàn)多線程之間的變量同步,也就是在沒有線程被阻塞的情況下實(shí)現(xiàn)變量的同步,所以也叫非阻塞同步Non-blocking?Synchronization
    2022-10-10
  • 使用Go語言實(shí)現(xiàn)心跳機(jī)制

    使用Go語言實(shí)現(xiàn)心跳機(jī)制

    心跳最典型的應(yīng)用場(chǎng)景是是探測(cè)服務(wù)是否存活,這篇文章主要來和大家介紹一下如何使用Go語言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的心跳程序,感興趣的可以了解下
    2024-01-01
  • 一文解析 Golang sync.Once 用法及原理

    一文解析 Golang sync.Once 用法及原理

    這篇文章主要介紹了一文解析 Golang sync.Once 用法及原理,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • Golang的第一個(gè)程序-Hello?World

    Golang的第一個(gè)程序-Hello?World

    這篇文章主要介紹了第一個(gè)Go程序-Hello?World,在編寫第一個(gè)go程序之前,我們要將系統(tǒng)的環(huán)境變量配好,下面來看具體的編一過程吧,需要的小伙伴可以參考一下
    2022-01-01
  • GoLang中拼接字符串性能優(yōu)化方法詳解

    GoLang中拼接字符串性能優(yōu)化方法詳解

    最近在做性能優(yōu)化,有個(gè)函數(shù)里面的耗時(shí)特別長(zhǎng),看里面的操作大多是一些字符串拼接的操作,而字符串拼接在 golang 里面其實(shí)有很多種實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于Golang語言如何高效拼接字符串的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • Gorm更新零值問題解決思路與過程

    Gorm更新零值問題解決思路與過程

    這篇文章主要介紹了Gorm更新零值問題解決思路與過程,總的來說這并不是一道難題,那為什么要拿出這道題介紹?拿出這道題真正想要傳達(dá)的是解題的思路,以及不斷優(yōu)化探尋最優(yōu)解的過程。希望通過這道題能給你帶來一種解題優(yōu)化的思路
    2023-01-01
  • 詳解golang中的閉包與defer

    詳解golang中的閉包與defer

    閉包一個(gè)函數(shù)與其相關(guān)的引用環(huán)境組合的一個(gè)實(shí)體,其實(shí)可以理解為面向?qū)ο笾蓄愔械膶傩耘c方法,這篇文章主要介紹了golang的閉包與defer,需要的朋友可以參考下
    2022-09-09

最新評(píng)論