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

Go語言快速入門指針Map使用示例教程

 更新時間:2022年08月07日 17:08:38   作者:程序員小喬  
這篇文章主要為大家介紹了Go語言快速入門指針Map示例教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

1. 指針

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

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

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

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

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

1.1 指針地址和指針類型

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

Go語言中的值類型(int、float、boolstring、arraystruct)都有對應的指針類型,如:*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?//?指針取值(根據(jù)指針去內(nèi)存取值)
????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

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

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

  • 對變量進行取地址(&)操作,可以獲得這個變量的指針變量。
  • 指針變量的值是指針地址。
  • 對指針變量進行取值(*)操作,可以獲得指針變量指向的原變量的值。
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是一個內(nèi)置的函數(shù),它的函數(shù)簽名如下:

func?new(Type)?*Type

其中:

  • Type表示類型,new函數(shù)只接受一個參數(shù),這個參數(shù)是一個類型
  • *Type表示類型指針,new函數(shù)返回一個指向該類型內(nèi)存地址的指針。

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

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但是沒有初始化,指針作為引用類型需要初始化后才會擁有內(nèi)存空間,才可以給它賦值。應該按照如下方式使用內(nèi)置的new函數(shù)對a進行初始化之后就可以正常對其賦值了:

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

make也是用于內(nèi)存分配的,區(qū)別于new,它只用于slice、map以及chan的內(nèi)存創(chuàng)建,而且它返回的類型就是這三個類型本身,而不是他們的指針類型,因為這三種類型就是引用類型,所以就沒有必要返回他們的指針了。

1.5 new與make的區(qū)別

  • 二者都是用來做內(nèi)存分配的。
  • make只用于slicemap以及channel的初始化,返回的還是這三個引用類型本身;
  • new用于類型的內(nèi)存分配,并且內(nèi)存對應的值為類型零值,返回的是指向類型的指針。

2. Map

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

2.1 什么是Map

key,value存儲

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

hash沖突

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

hash沖突的常見解決方法

  • 開放定址法: 也就是說當我們存儲一個key,value時,發(fā)現(xiàn)hashkey(key)的下標已經(jīng)被別key占用,那我們在這個數(shù)組中空間中重新找一個沒被占用的存儲這個沖突的key,那么沒被占用的有很多,找哪個好呢?常見的有:線性探測法,線性補償探測法,隨機探測法,這里以線性探測為對比。
  • 拉鏈法: 何為拉鏈,簡單理解為鏈表,當keyhash沖突時,我們在沖突位置的元素上形成一個鏈表,通過指針互連接,當查找時,發(fā)現(xiàn)key沖突,順著鏈表一直往下找,直到鏈表的尾節(jié)點,找不到則返回空。

開放定址(線性探測)和拉鏈的優(yōu)缺點

  • 拉鏈法比線性探測處理簡單
  • 線性探測查找是會被拉鏈法會更消耗時間
  • 線性探測會更加容易導致擴容,而拉鏈不會
  • 拉鏈存儲了指針,所以空間上會比線性探測占用多一點
  • 拉鏈是動態(tài)申請存儲空間的,所以更適合鏈長不確定的

2.2 Map 定義

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

map[KeyType]ValueType

其中:

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

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

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

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

2.3 map基本使用

map中的數(shù)據(jù)都是成對出現(xiàn)的,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()函數(shù)刪除鍵值對

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

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使用示例教程的詳細內(nèi)容,更多關于Go語言入門指針Map教程的資料請關注腳本之家其它相關文章!

相關文章

  • 深入理解Golang的反射reflect示例

    深入理解Golang的反射reflect示例

    本文主要介紹了Golang的反射reflect示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 使用golang寫一個redis-cli的方法示例

    使用golang寫一個redis-cli的方法示例

    這篇文章主要介紹了使用golang寫一個redis-cli的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-10-10
  • Go語言入門exec的基本使用示例

    Go語言入門exec的基本使用示例

    這篇文章主要為大家介紹了Go語言入門exec在go語言中的基本使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • 解決 Golang VS Code 插件下載安裝失敗的問題

    解決 Golang VS Code 插件下載安裝失敗的問題

    這篇文章主要介紹了解決 Golang VS Code 插件下載安裝失敗,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-05-05
  • Golang打包go項目部署到linux服務器正確方法

    Golang打包go項目部署到linux服務器正確方法

    這篇文章主要給大家介紹了關于Golang打包go項目部署到linux服務器的正確方法,Go?是一個開源的編程語言,它能讓構造簡單、可靠且高效的軟件變得容易,具有簡潔、快速、安全,并行、有趣、開源,內(nèi)存管理、v數(shù)組安全、編譯迅速的特征,需要的朋友可以參考下
    2023-10-10
  • Go設計模式之迭代器模式講解和代碼示例

    Go設計模式之迭代器模式講解和代碼示例

    迭代器是一種行為設計模式, 讓你能在不暴露復雜數(shù)據(jù)結構內(nèi)部細節(jié)的情況下遍歷其中所有的元素,本文將為大家詳細介紹Go 迭代器模式,文中詳細的代碼示例,需要的朋友可以參考下
    2023-07-07
  • Bililive-go 實現(xiàn)直播自動監(jiān)控錄制功能

    Bililive-go 實現(xiàn)直播自動監(jiān)控錄制功能

    最近有直播錄制的需求,但是自己手動錄制太麻煩繁瑣,于是用了開源項目Bililive-go進行全自動監(jiān)控錄制,對Bililive-go 直播自動監(jiān)控錄制實現(xiàn)思路感興趣的朋友,一起看看吧
    2024-03-03
  • go語言中http超時引發(fā)的事故解決

    go語言中http超時引發(fā)的事故解決

    我們使用的是golang標準庫的http client,對于一些http請求,我們在處理的時候,會考慮加上超時時間,如果超時可能會引起報錯,本文就記一次超時引發(fā)的事故
    2021-06-06
  • 在Go中實現(xiàn)和使用堆棧以及先進先出原則詳解

    在Go中實現(xiàn)和使用堆棧以及先進先出原則詳解

    Go是一種功能強大的編程語言,提供了豐富的數(shù)據(jù)結構和算法,堆棧是計算機科學中的基本數(shù)據(jù)結構之一,在本博文中,我們將探討如何在?Go?中實現(xiàn)和使用堆棧,以及堆棧如何遵循先進先出?(FIFO)?原則
    2023-10-10
  • 一篇文章說清楚?go?get?使用私有庫的方法

    一篇文章說清楚?go?get?使用私有庫的方法

    這篇文章主要介紹了go?get?如何使用私有庫,本文會明確指出Git?、golang的配置項,附送TortoiseGit?+?Git混合配置,需要的朋友可以參考下
    2022-09-09

最新評論