Go語言之對映(map)快速入門篇

尹正杰發表於2024-07-26

                                              作者:尹正傑

版權宣告:原創作品,謝絕轉載!否則將追究法律責任。

目錄
  • 一.對映(map)定義
    • 1.對映(map)概述
    • 2.map的語法格式
    • 3.map的三種建立方式
      • 3.1 先宣告在make
      • 3.2 直接使用make初始化map
      • 3.3 直接賦值初始化map
  • 二.map基本使用
    • 1.map的增刪改查
    • 2.map的遍歷
    • 3.巢狀map遍歷
    • 4.元素為map型別的切片
    • 5.值為切片型別的map
  • 三.練習題
    • 1.寫一個程式,統計一個字串中每個單詞出現的次數
    • 2.看程式碼手寫結果

一.對映(map)定義

1.對映(map)概述

對映(map)是一種無序的基於key-value的資料結構,Go語言中的map是引用型別,必須初始化才能使用。

Go語言中提供的對映關係容器為map,其內部使用雜湊表(hash)實現。

對映(map)是Go語言中內建的一種型別,它將鍵值相關聯,我們可以透過key來獲取對應的value,有點類似於其他語言的集合。

對映(map)的特點:
	- 1.map結合在使用前一定要make;
	- 2.map的key-value是無序的;
	- 3.key是不可以重複的,如果遇到重複,後一個value會替換前一個value;
	- 4.不同的key,其value是可以重複的;

2.map的語法格式

Go語言中map的定義語法如下:
	map[KeyType]ValueType
	
map型別的變數預設初始值為nil,需要使用make()函式來分配記憶體。語法為:
	make(map[KeyType]ValueType, [cap])
	
	相關欄位說明:
    KeyType:
      表示鍵的型別。
    ValueType:
      表示鍵對應的值的型別。
    cap
      map的容量,該引數可選,但建議在初始化map的時候就為其指定一個合適的容量。
      
溫馨提示:
	- 1.key,value的型別包括但不限於bool,數值型,string,指標,chan,還可以只包含前面幾個型別的介面,結構體,陣列等;
	- 2.key部分通常為int,string型別,value通常為數字(整數,浮點數),string,map,結構體;
	- 3.key部分不可以是slice,map,function等型別;

3.map的三種建立方式

3.1 先宣告在make

package main

import "fmt"

func main() {

	// 1.宣告map變數,但並沒有分配堆記憶體空間
	var dongMan map[int]string

	// 2.必須透過make函式進行初始化,才會在堆記憶體中分配空間
	dongMan = make(map[int]string, 5) // map可以存放5個鍵值對,但實際儲存超過5個依舊是可以的

	// 3.將鍵值對儲存map中
	dongMan[20230925] = "《仙逆》"
	dongMan[20200725] = "《凡人修仙傳》"
	dongMan[20201129] = "《吞噬星空》"
	dongMan[20220129] = "《永生》"
	dongMan[20140731] = "《畫江湖之不良人》"
	dongMan[20131214] = "《師兄啊師兄》"
	dongMan[20021003] = "《火影忍者》"
	dongMan[20080517] = "《葫蘆兄弟》"
	dongMan[19990723] = "《西遊記》"

	// 4.輸出集合
	fmt.Printf("dongman = %v\n", dongMan)
}

3.2 直接使用make初始化map

package main

import "fmt"

func main() {

	// 1.初始化map型別
	language := make(map[string]uint16)

	// 2.賦值
	language["C"] = 1972
	language["C++"] = 1983
	language["Python"] = 1989
	language["JAVA"] = 1995
	language["Golang"] = 2007
	language["Scala"] = 2003
	language["Ruby"] = 1993
	language["Php"] = 2004
	language["HTML"] = 1989
	language["CSS"] = 1994
	language["JavaScript"] = 1995

	// 3.檢視map資料
	fmt.Printf("language = [%v]\n", language)
}

3.3 直接賦值初始化map

package main

import "fmt"

func main() {

	dbInfo := map[string]string{
		"Username": "jasonyin2020",
		"Password": "yinzhengjie",
		"DbHost":   "www.yinzhengjie.com",
		"DbPort":   "3306",
		"DbName":   "wordpress",
	}

	fmt.Printf("userInfo = %v\n", dbInfo)
}

二.map基本使用

1.map的增刪改查

package main

import "fmt"

func main() {
	// 1.定義map
	constellation := make(map[string]string)

	// 2.增加
	constellation["金牛座"] = "土象星座: 0420-0520"
	constellation["處女座"] = "土象星座: 0823-0922"
	constellation["摩羯座"] = "土象星座: 1222-0119"

	// 3.修改
	constellation["獅子座"] = "火象星座: 0723-0822"

	fmt.Printf("刪除前: len(constellation) = %d\n", len(constellation))

	// 4.刪除指定map的key,若key不存在,並不會報錯
	delete(constellation, "摩羯座")
	fmt.Printf("刪除後: len(constellation) = %d\n", len(constellation))

	// 5.查詢,判斷某個鍵是否存在
	value, ok := constellation["獅子座"]
	if ok {
		fmt.Printf("獅子座的出生日期: %v\n", value)
	} else {
		fmt.Println("查無此人")
	}

	fmt.Printf("星座: %v\n", constellation)

}

2.map的遍歷

package main

import "fmt"

func main() {
	constellation := make(map[string]string)

	constellation["金牛座"] = "土象星座: 0420-0520"
	constellation["處女座"] = "土象星座: 0823-0922"
	constellation["摩羯座"] = "土象星座: 1222-0119"
	constellation["獅子座"] = "火象星座: 0723-0822"

	// Go語言中使用for range遍歷map,遍歷map時的元素順序與新增鍵值對的順序無關。
	for key, value := range constellation {
		fmt.Printf("key = %v, value = %v\n", key, value)
	}

	fmt.Println("----- 我是分割線 -----")

	// 但我們只想遍歷key的時候,僅需使用一個引數來接收喲~
	for k := range constellation {
		fmt.Printf("key = %v\n", k)
	}

}

3.巢狀map遍歷

package main

import "fmt"

func main() {

	dongMan := make(map[string]map[int]string)

	// 由於map的值為map型別,因此我們需要對值先進行make再使用,否則會丟擲異常
	dongMan["騰訊影片"] = make(map[int]string, 3)
	dongMan["騰訊影片"][20230925] = "《仙逆》"
	dongMan["騰訊影片"][20201129] = "《吞噬星空》"
	dongMan["騰訊影片"][20140731] = "《畫江湖之不良人》"

	// 由於map的值為map型別,因此我們需要對值先進行make再使用,否則會丟擲異常
	dongMan["B站"] = make(map[int]string, 2)
	dongMan["B站"][20200725] = "《凡人修仙傳》"
	dongMan["B站"][20220129] = "《永生》"

	// 由於map的值為map型別,因此我們需要對值先進行make再使用,否則會丟擲異常
	dongMan["優酷"] = make(map[int]string, 2)
	dongMan["優酷"][20131214] = "《師兄啊師兄》"
	dongMan["優酷"][20021003] = "《火影忍者》"

	for k1, v1 := range dongMan {
		fmt.Printf("k1 = %v\n", k1)

		for k2, v2 := range v1 {
			fmt.Printf("[%v]動漫的發行時間是: [%d]\n", v2, k2)
		}
	}
}

4.元素為map型別的切片

package main

import (
	"fmt"
)

func main() {
	// 定義一個長度為3的切片
	var mapSlice = make([]map[string]string, 3)

	// 對切片的各個元素進行遍歷
	for index, value := range mapSlice {
		fmt.Printf("index: %d value: %v\n", index, value)
	}
	
	fmt.Println("----- 分割線 -----")

	// 對切片中的第一個(索引下標為0)map元素進行初始化
	mapSlice[0] = make(map[string]string, 10)
	mapSlice[0]["name"] = "Jason Yin"
	mapSlice[0]["password"] = "123456"
	mapSlice[0]["address"] = "北京市昌平區沙河鎮"

	for index, value := range mapSlice {
		fmt.Printf("index: %d value: %v\n", index, value)
	}
}

5.值為切片型別的map

package main

import (
	"fmt"
)

func main() {
	// 定義一個map型別
	var sliceMap = make(map[string][]string, 3)

	key := "中國"
	value, ok := sliceMap[key]
	if !ok {
		// 如果key="中國"不存在,則對其值進行初始化為一個容量為2的字串切片。
		value = make([]string, 0, 2)
	}

	// 緊接著,由於切片是引用型別,我們往該切片中新增2個字串型別元素
	value = append(value, "北京", "上海")

	fmt.Printf("地址: %p, 資料: %v, 長度: %d, 容量: %d\n", value, value, len(value), cap(value))

	// 往切片追加元素,原有的切片底層陣列將存不下,於是會產生新的底層陣列喲~
	value = append(value, "深圳", "石家莊", "西安")
	fmt.Printf("地址: %p, 資料: %v, 長度: %d, 容量: %d\n", value, value, len(value), cap(value))

	// 注意,此處我們切片進行賦值給map的key。
	sliceMap[key] = value
	fmt.Println(sliceMap)
}

三.練習題

1.寫一個程式,統計一個字串中每個單詞出現的次數

package main

import (
	"fmt"
	"strings"
)

func main() {

	// 統計一個字串中每個單詞出現的次數
	s1 := "I love you , and you ?"

	// 將字串按照空格子串進行切割
	res := strings.Split(s1, " ")

	// 初始化用於單詞統計的map
	var wordCount = make(map[string]int, 10)

	// 如果單詞不存在,則將其值設定為1,若存在,則將其值進行加一操作。
	for _, value := range res {
		_, ok := wordCount[value]
		if !ok {
			wordCount[value] = 1
		} else {
			wordCount[value]++
		}
	}

	// 遍歷字典
	for k, v := range wordCount {
		fmt.Printf("%s: %d\n", k, v)
	}

}

2.看程式碼手寫結果

package main

import (
	"fmt"
)

func main() {
	// 自定義一個Map型別,底層對應的是一個map型別喲~
	type Map map[string][]int

	// 初始化咱們的自定義型別
	m := make(Map)
	s1 := []int{100, 200}
	s1 = append(s1, 300)
	fmt.Printf("s1 = %+v\n", s1)

	m["JasonYin"] = s1
	s1 = append(s1[:1], s1[2:]...)
	fmt.Printf("s1 = %+v\n", s1)
	fmt.Printf("m['JasonYn'] = %+v\n", m["JasonYin"])
}

相關文章