中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

Go語言的指針Map如何使用

發布時間:2022-08-08 11:25:15 來源:億速云 閱讀:229 作者:iii 欄目:開發技術

這篇文章主要介紹“Go語言的指針Map如何使用”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Go語言的指針Map如何使用”文章能幫助大家解決問題。

    1. 指針

    區別于C/C++中的指針,Go語言中的指針不能進行偏移和運算,是安全指針。

    要搞明白Go語言中的指針需要先知道3個概念:指針地址、指針類型和指針取值。

    Go語言中的函數傳參都是值拷貝,當我們想要修改某個變量的時候,我們可以創建一個指向該變量地址的指針變量。

    傳遞數據使用指針,而無須拷貝數據。類型指針不能進行偏移和運算。

    Go語言中的指針操作非常簡單,只需要記住兩個符號:&(取地址)和*(根據地址取值)。

    1.1 指針地址和指針類型

    每個變量在運行時都擁有一個地址,這個地址代表變量在內存中的位置。Go語言中使用&字符放在變量前面對變量進行“取地址”操作。

    Go語言中的值類型(intfloatboolstringarraystruct)都有對應的指針類型,如:*int*int64*string等。

    取變量指針的語法如下:

    ptr := &v    // v的類型為T

    其中:

    • v:代表被取地址的變量,類型為T

    • ptr:用于接收地址的變量,ptr的類型就為*T,稱做T的指針類型。*代表指針。

    package main
    import "fmt"
    func main() {
        a := 10
        b := &a
        fmt.Printf("a:%d ptr:%p\n", a, &a) // a:10 ptr:0xc00001a078
        fmt.Printf("b:%p type:%T\n", b, b) // b:0xc00001a078 type:*int
        fmt.Println(&b)                    // 0xc00000e018
    }

    1.2 指針取值

    在對普通變量使用&操作符取地址后會獲得這個變量的指針,然后可以對指針使用*操作,也就是指針取值。

    package main
    import "fmt"
    func main() {
        //指針取值
        a := 10
        b := &a // 取變量a的地址,將指針保存到b中
        fmt.Printf("type of b: %T\n", b)
        c := *b // 指針取值(根據指針去內存取值)
        fmt.Printf("type of c: %T\n", c)
        fmt.Printf("value of c: %v\n", c)
    }

    輸出結果:

    type of b: *int
    type of c: int
    value of c: 10

    取地址操作符&和取值操作符*是一對互補操作符,&取出地址,*根據地址取出地址指向的值。

    變量、指針地址、指針變量、取地址、取值的相互關系和特性如下:

    • 對變量進行取地址(&)操作,可以獲得這個變量的指針變量。

    • 指針變量的值是指針地址。

    • 對指針變量進行取值(*)操作,可以獲得指針變量指向的原變量的值。

    package main
    import "fmt"
    func p1(n int) {
        n = 100
    }
    func p2(n *int) {
        *n = 100
    }
    func main() {
        a := 10
        p1(a)
        fmt.Println(a) // 10
        p2(&a)
        fmt.Println(a) // 100
    }

    1.3 空指針

    • 當一個指針被定義后沒有分配到任何變量時,它的值為 nil

    • 空指針的判斷

    package main
    import "fmt"
    func main() {
        var p *string
        fmt.Printf("p的值是%v \n", p)
        if p != nil {
            fmt.Println("非空指針")
        } else {
            fmt.Println("空指針")
        }
    }

    1.4 new 的使用

    new是一個內置的函數,它的函數簽名如下:

    func new(Type) *Type

    其中:

    • Type表示類型,new函數只接受一個參數,這個參數是一個類型

    • *Type表示類型指針,new函數返回一個指向該類型內存地址的指針。

    new函數不太常用,使用new函數得到的是一個類型的指針,并且該指針對應的值為該類型的零值。

    func main() {
        a := new(int)
        b := new(bool)
        fmt.Printf("%T\n", a) // *int
        fmt.Printf("%T\n", b) // *bool
        fmt.Println(*a)       // 0
        fmt.Println(*b)       // false
    }

    var a *int只是聲明了一個指針變量a但是沒有初始化,指針作為引用類型需要初始化后才會擁有內存空間,才可以給它賦值。應該按照如下方式使用內置的new函數對a進行初始化之后就可以正常對其賦值了:

    func main() {
        var a *int
        a = new(int)
        *a = 10
        fmt.Println(*a)
    }

    make也是用于內存分配的,區別于new,它只用于slicemap以及chan的內存創建,而且它返回的類型就是這三個類型本身,而不是他們的指針類型,因為這三種類型就是引用類型,所以就沒有必要返回他們的指針了。

    1.5 new與make的區別

    • 二者都是用來做內存分配的。

    • make只用于slicemap以及channel的初始化,返回的還是這三個引用類型本身;

    • new用于類型的內存分配,并且內存對應的值為類型零值,返回的是指向類型的指針。

    2. Map

    map是一種無序的基于key-value的數據結構,Go語言中的map是引用類型,必須初始化才能使用。

    2.1 什么是Map

    key,value存儲

    最通俗的話說:Map是一種通過key來獲取value的一個數據結構,其底層存儲方式為數組,在存儲時key不能重復,當key重復時,value進行覆蓋,我們通過key進行hash運算(可以簡單理解為把key轉化為一個整形數字)然后對數組的長度取余,得到key存儲在數組的哪個下標位置,最后將keyvalue組裝為一個結構體,放入數組下標處。

    hash沖突

    數組一個下標處只能存儲一個元素,也就是說一個數組下標只能存儲一對keyvaluehashkey(xiaoming)=4占用了下標0的位置,假設我們遇到另一個keyhashkey(xiaowang)也是4,這就是hash沖突(不同的key經過hash之后得到的值一樣),那么key=xiaowang的怎么存儲?

    hash沖突的常見解決方法
    • 開放定址法: 也就是說當我們存儲一個keyvalue時,發現hashkey(key)的下標已經被別key占用,那我們在這個數組中空間中重新找一個沒被占用的存儲這個沖突的key,那么沒被占用的有很多,找哪個好呢?常見的有:線性探測法,線性補償探測法,隨機探測法,這里以線性探測為對比。

    • 拉鏈法: 何為拉鏈,簡單理解為鏈表,當keyhash沖突時,我們在沖突位置的元素上形成一個鏈表,通過指針互連接,當查找時,發現key沖突,順著鏈表一直往下找,直到鏈表的尾節點,找不到則返回空。

    開放定址(線性探測)和拉鏈的優缺點
    • 拉鏈法比線性探測處理簡單

    • 線性探測查找是會被拉鏈法會更消耗時間

    • 線性探測會更加容易導致擴容,而拉鏈不會

    • 拉鏈存儲了指針,所以空間上會比線性探測占用多一點

    • 拉鏈是動態申請存儲空間的,所以更適合鏈長不確定的

    2.2 Map 定義

    Go語言中 Map的定義語法如下:

    map[KeyType]ValueType

    其中:

    • KeyType: 表示鍵的類型。

    • ValueType: 表示鍵對應的值的類型。

    map類型的變量默認初始值為nil,需要使用make()函數來分配內存。語法為:

     make(map[KeyType]ValueType, [cap])

    其中cap表示map的容量,該參數雖然不是必須的,但是我們應該在初始化map的時候就為其指定一個合適的容量。

    2.3 map基本使用

    map中的數據都是成對出現的,map的基本使用如下:

    func main() {
        scoreMap := make(map[string]int, 8)
        scoreMap["張三"] = 90
        scoreMap["李四"] = 100
        fmt.Println(scoreMap)
        fmt.Println(scoreMap["李四"])
        fmt.Printf("type of a: %T\n", scoreMap)
    }

    輸出結果:

    map[李四:100 張三:90]
    100
    type of a: map[string]int

    map也支持在聲明的時候填充元素:

    func main() {
        userInfo := map[string]string{
            "username": "admin",
            "password": "123456",
        }
        fmt.Println(userInfo)
    }

    2.4 map的遍歷

    Go語言中使用for range遍歷map:

    func main() {
        scoreMap := make(map[string]int)
        scoreMap["張三"] = 90
        scoreMap["李四"] = 100
        scoreMap["王五"] = 60
        for k, v := range scoreMap {
            fmt.Println(k, v)
        }
    }

    如果只想遍歷key的時候,可以按下面的寫法:

    func main() {
        scoreMap := make(map[string]int)
        scoreMap["張三"] = 90
        scoreMap["李四"] = 100
        scoreMap["王五"] = 60
        for k := range scoreMap {
            fmt.Println(k)
        }
    }

    注意: 遍歷map時的元素順序與添加鍵值對的順序無關。

    2.5 map判斷某個鍵是否存在

    Go語言中有個判斷map中鍵是否存在的特殊寫法,格式如下:

    value, ok := map[key]

    如果key存在oktrue,value為對應的值;不存在okfalse,value為值類型的零值

    func main() {
        scoreMap := make(map[string]int)
        scoreMap["張三"] = 90
        scoreMap["李四"] = 100
        // 如果key存在ok為true,value為對應的值;不存在ok為false,value為值類型的零值
        value, ok := scoreMap["張三"]
        if ok {
            fmt.Println(v)
        } else {
            fmt.Println("查無此人")
        }
    }

    2.6 map使用delete()函數刪除鍵值對

    使用delete()內建函數從map中刪除一組鍵值對, delete()函數的格式如下:

    delete(map, key)

    其中:

    • map: 表示要刪除鍵值對的map

    • key: 表示要刪除的鍵值對的鍵

    func main(){
        scoreMap := make(map[string]int)
        scoreMap["張三"] = 90
        scoreMap["李四"] = 100
        scoreMap["王五"] = 60
        delete(scoreMap, "李四")//將李四: 100從 map 中刪除
        for k,v := range scoreMap{
            fmt.Println(k, v)
        }
    }

    關于“Go語言的指針Map如何使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

    向AI問一下細節

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

    AI

    林口县| 丘北县| 谷城县| 平度市| 大同市| 新兴县| 漾濞| 汉阴县| 镶黄旗| 宕昌县| 长岭县| 榕江县| 宽城| 鞍山市| 赤壁市| 伊金霍洛旗| 潼南县| 裕民县| 江城| 共和县| 喀什市| 襄汾县| 凤山市| 泽州县| 阿荣旗| 霍城县| 仁布县| 灵宝市| 康平县| 板桥市| 绥阳县| 安远县| 克拉玛依市| 昭觉县| 额尔古纳市| 安平县| 那坡县| 永济市| 梅州市| 丰宁| 依安县|