網(wǎng)站首頁 編程語言 正文
前言
今天咱們來學(xué)習(xí)一下golang中的map數(shù)據(jù)類型,單純的總結(jié)一下基本語法和使用場景,也不具體深入底層。map類型是什么呢?做過PHP的,對于數(shù)組這種數(shù)據(jù)類型是一點也不陌生了。PHP中的數(shù)組分為索引數(shù)組
和關(guān)聯(lián)數(shù)組
。例如下面的代碼:
// 索引數(shù)組【數(shù)組的key是一個數(shù)字, 從0,1,2開始遞增】 $array = [1, '張三', 12]; // 關(guān)聯(lián)數(shù)組【數(shù)組的key是一個字符串,可以自定義key的名稱】 $array = ['id' => 1, 'name' => '張三', 'age' => 12];
在golang中,map是一種特殊的數(shù)據(jù)結(jié)構(gòu),是一種key對應(yīng)一個value類型的結(jié)構(gòu)。這種結(jié)構(gòu)可以被稱為關(guān)聯(lián)數(shù)組和字典。
在golang中也有切片和數(shù)組這樣的數(shù)據(jù)類型,來存儲一組數(shù)據(jù)。
- 數(shù)組就好比PHP中的一維數(shù)組,并且長度是固定的,其中的值類型在定義數(shù)組的時候就確定好了。
- 切片是一種特殊的數(shù)組類型。長度是固定的。
// 數(shù)組,類型是int,長度是4。 array := [4]int{1, 2, 3, 4} // 切片,類型是int,長度不固定。 slice := []int{1, 2, 3, 4}
有數(shù)組和切片可以存儲一組數(shù)據(jù),那為什么還有map這樣的類型結(jié)構(gòu)呢?map類型具體是啥樣的呢?
案例
假設(shè)我們現(xiàn)在有這樣的一個需求,要用golang中的一種數(shù)據(jù)類型來存儲多個用戶的數(shù)據(jù),這些數(shù)據(jù)分別用戶的ID,name,age,sex…等等字段。我們改用什么數(shù)據(jù)類型呢?
在PHP中我們可以直接下面的方式定義,操作也是非常簡單。
$userInfo = [ ['id' => 1, 'name' => '張三', 'age' => 12, 'sex' => '男'], ['id' => 2, 'name' => '趙六', 'age' => 22, 'sex' => '男'], ['id' => 3, 'name' => '李四', 'age' => 34, 'sex' => '女'], ['id' => 4, 'name' => '王麻子', 'age' => 56, 'sex' => '男'] ];
那如何在golang中實現(xiàn)呢,假設(shè)我們用數(shù)組和切片實現(xiàn)一下試試。
// 1. 用數(shù)組實現(xiàn) $user1 := [4]string{"1", "張三", "12", "男"} $user2 := [4]string{"2", "趙六", "12", "男"} $user3 := [4]string{"3", "李四", "12", "女"} $user4 := [4]string{"4", "王麻子", "12", "男"} // 2. 用戶切片實現(xiàn) $user1 := []string{"1", "張三", "12", "男"} $user2 := []string{"2", "趙六", "12", "男"} $user3 := []string{"3", "李四", "12", "女"} $user4 := []string{"4", "王麻子", "12", "男"}
通過上面的示例代碼,我們是不是看得出來存在這樣幾個問題:
- a. 可讀性低。我們完全不知道1、12這樣的值是用戶的什么信息,男、張三我們還可以猜測一下是名字和性別。
- b. 重復(fù)代碼。一個用戶一個變量,如果存在千萬個用戶,我們豈不是需要定義千萬個變量。
- c. 繁瑣。相比PHP的實現(xiàn),是不是非常繁瑣。PHP中直接定義一個變量,通過多維數(shù)組的方式,就可以定義key和值。清晰并且簡單。這也是為什么大家都說PHP中的數(shù)組非常強大和好用了。
通過切片和數(shù)組實現(xiàn)的方式,我們知道了弊端。那有不有一種數(shù)據(jù)類型能夠像PHP這樣簡單就能實現(xiàn)呢?這樣的場景就可以用map實現(xiàn)PHP這樣的定義結(jié)構(gòu)。接下來,我們就具體總結(jié)一下map相關(guān)的操作。
map
map定義
map 是一種特殊的數(shù)據(jù)結(jié)構(gòu):一種元素對(pair)的無序集合,pair 的一個元素是 key,對應(yīng)的另一個元素是 value,所以這個結(jié)構(gòu)也稱為關(guān)聯(lián)數(shù)組或字典。這是一種快速尋找值的理想結(jié)構(gòu):給定 key,對應(yīng)的 value 可以迅速定位。
map 這種數(shù)據(jù)結(jié)構(gòu)在其他編程語言中也稱為字典(Python)、hash 和 HashTable 等。
map聲明
map屬于一種引用類型,在使用時我們需要make給其分配內(nèi)存空間,未分配內(nèi)存空間的map值是一個nil。
map聲明時,需要指定key的類型和值的類型,并且復(fù)制時,必須按照定義時的類型進行復(fù)制。 map的值可以是任意類型,可以是切片可以是數(shù)組,可以是接口、結(jié)構(gòu)體、指針、字符串等等數(shù)據(jù)類型。 var map1 map[key類型]值類型 // 聲明方式一,完整模式 var map1 map[int]string map1 = make(map[int]string[, n]) // 聲明方式二,段語法風(fēng)格 map1 := make(map[int]string[, n])
上面的n都是map的容量,也就是說map可以存儲元素的數(shù)量??梢允÷?,map會動態(tài)擴容。
示例小案例,我們用map存儲一個用戶的信息。用戶信息包含ID,name,age字段。
userInfo := make(map[string]string) userInfo["id"] = "1" userInfo["name"] = "張三" userInfo["age"] = "12" fmt.Println(userInfo) // output map[id:1 name:張三 age:12]
因為用戶信息的字段和字段值有字符串和數(shù)字類型,定義好類型之后就只能傳對應(yīng)類型的值,因此我們給key和value的類型都定義為string類型。
map的操作
這里的操作,我們接著上面的小案例來使用。
- 訪問和復(fù)制。我們直接使用下標(biāo)就可以了。
// 賦值 mapName[key] = "值" userInfo["name"] = "王五" // 訪問 mapName[key] name := userInfo["name"]
- 刪除元素。刪除操作,需要使用到delete(),給該函數(shù)傳遞要刪除的key。
delete(mapName, key) delete(userInfo, "name")
- 判斷某一個值key是否存在。上面我們訪問map中的key,直接使用下標(biāo)就可以了。如果 map 中不存在 key1,val1 就是一個值類型的空值。會導(dǎo)致我們沒法區(qū)分到底是 key不存在還是它對應(yīng)的value就是空值。
value, boolean := mapName[key] // 如果boolean是一個true則說明,對應(yīng)的key存在,如果是false,則說明該key不存在。 if value, ok := userInfo["address"]; !ok { fmt.Println("address key not found!") } //因為address這個key不存在,因此會輸出“address key not found!”。
- 循環(huán)。循環(huán)map,我們一般是用到?
for range
來實現(xiàn)。
// 語法 for value, key := range mapName { fmt.Println(key, "=>", value) } // 示例 for value, key := range userInfo { fmt.Println(key, "=>", value) } // output 1 => id 張三 => name 12 => age
總結(jié)
其實對map基本的操作就是這么簡單。對它的理解也是這么簡單。在日常開發(fā)中,我們也經(jīng)常使用該類型。
回到最上面多個用戶的案例,這時候我們是不是就知道怎么使用map實現(xiàn)了。
- 因為是多個用戶,我們是不是需要定義多維的map結(jié)構(gòu)。
- map的一級key是int,表示當(dāng)前的用戶序號(從0,1,2,3…依次遞增)。key對應(yīng)的值,才是某一個用戶的具體信息,我們同樣的定義map類型來存儲,key和value都是字符串,結(jié)構(gòu)就像map聲明中的小案例一樣。
- 因為我們不知道用戶的具體個數(shù),我們將一級的key定義為切片。因為切片的長度是不固定的。
userInfo := make([]map[string]string, 3) for i := 0; i < 3; i++ { userInfo[i] = make(map[string]string, 3) userInfo[i]["id"] = "ID" userInfo[i]["name"] = "名稱" userInfo[i]["age"] = "年齡" } fmt.Println(userInfo) // output [ map[id:ID name:名稱 age:年齡] map[id:ID name:名稱 age:年齡] map[id:ID name:名稱 age:年齡] ]
為什么要兩次make,因為切片和map在golang中都是引用類型。第一次在make時,是針對切片初始化內(nèi)存空間,第二次是針對切片的key對應(yīng)的元素分配內(nèi)存空間。大致的結(jié)構(gòu)就像下圖一樣。
原文鏈接:https://blog.51cto.com/u_10992108/4652560
相關(guān)推薦
- 2022-11-18 Python正則表達式re.sub()用法詳解_python
- 2022-08-12 如何實現(xiàn)在pycharm中將.ui文件轉(zhuǎn)化為.py文件_python
- 2022-05-19 分享Python獲取本機IP地址的幾種方法_python
- 2023-07-27 Android解決全屏?xí)r虛擬導(dǎo)航欄留一截的問題
- 2022-09-05 詳解apache編譯安裝httpd-2.4.54及三種風(fēng)格的init程序特點和區(qū)別_Linux
- 2022-12-05 Django中使用AJAX的詳細過程_python
- 2023-07-09 Go 數(shù)組與切片的區(qū)別
- 2023-02-01 Python動態(tài)演示旋轉(zhuǎn)矩陣的作用詳解_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支