【Golang】Golang基础语法之内建容器(三):Map

发布于:2024-12-06 ⋅ 阅读:(145) ⋅ 点赞:(0)

Map

与 C++ 不同,Golang 的 Map 类型只有 map 一种,而 C++ 有 map 和 unordered_map。Golang 的 map 与 C++ 当中的 unorderd_map 类似,其底层均采用 hashmap 实现,因此 Golang 当中的 map 是无序的。

map 的定义

共有三种方法来对 map 进行定义:

第一种方法是显式地初始化一个 map,可以使用:=,但是必须给定 map 初值:

m := map[string]string{
	"name":    "try",
	"course":  "golang",
	"site":    "csdn",
	"quality": "spectacular",
}

第二种方法是使用内置的 make 函数:

m2 := make(map[string]int) // 可以使用内建的 make 完成 map 的定义

此时建立的是一个空的 map,没有进行显式地初始化,需要使用 make 函数。

第三种方法是使用 var 进行定义:

var m3 map[string]int // 可以使用 var 来定义 map

map 的遍历

可以使用 range 方法对 map 进行遍历:

fmt.Println("Traversing map") // 使用 range 对 m 进行遍历
for k, v := range m {
	fmt.Println(k, v)
} // k, v 是可以省略的, 可以只打印 k 👇
for k := range m {
	fmt.Println(k)
} // 也可以值用 value
for _, v := range m {
	fmt.Println(v)
}

map 的查询

可以直接通过 key 按照数组下标索引的方式得到对应的 value,返回值有两个,第一个值是返回值,第二个值是 bool,表示给定的 key 是否在 map 当中。如果给定的 key 不在 map 当中不会报错,而是返回一个 value 类型的默认值。

fmt.Println("Getting values")
courseName := m["course"]
fmt.Println(courseName)

// 现在对不存在的 key 进行查询
causeName := m["cause"]
fmt.Println(causeName) // 输出的是一个空串, 即 zero_value

causeName, ok := m["cause"]
fmt.Println(causeName, ok) // 使用 ok 这个 bool 表示 k 是否在 map 中

fmt.Println("Deleting values")
name, ok := m["name"]
fmt.Println(name, ok)
delete(m, "name")
name, ok = m["name"]
fmt.Println(name, ok)

什么样的类型可以作为 map 的 key

Golang 当中的 map 使用 hash,因此必须比较相等。

除了 slice/map/function 之外的其它内建类型都可以作为 map 的 key。

不包含 slice/map/function 的自定义类型也可以作为 map 的 key。

编译器负责检查 map 的 key 是否合法。

完整代码如下:

package main

import "fmt"

func main() {
	m := map[string]string{
		"name":    "try",
		"course":  "golang",
		"site":    "csdn",
		"quality": "spectacular",
	}

	m2 := make(map[string]int) // 可以使用内建的 make 完成 map 的定义
	// m2 是 empty map
	var m3 map[string]int // 可以使用 var 来定义 map
	// 而 m3 是 nil
	fmt.Println(m, m2, m3) // m2 和 m3 是空的map
	// nil 和 empty_map 在运算时可以混用

	fmt.Println("Traversing map") // 使用 range 对 m 进行遍历
	for k, v := range m {
		fmt.Println(k, v)
	} // k, v 是可以省略的, 可以只打印 k 👇
	for k := range m {
		fmt.Println(k)
	} // 也可以值用 value
	for _, v := range m {
		fmt.Println(v)
	}

	// Golang 当中的 map 是一个 hashmap, 元素在 map 当中的存储是无序的
	// 如果需要顺序, 需要对 key 进行排序
	// 具体的方法是把 map 加入到 slice 中, 对 slice 排序
	fmt.Println("Getting values")
	courseName := m["course"]
	fmt.Println(courseName)

	// 现在对不存在的 key 进行查询
	causeName := m["cause"]
	fmt.Println(causeName) // 输出的是一个空串, 即 zero_value

	causeName, ok := m["cause"]
	fmt.Println(causeName, ok) // 使用 ok 这个 bool 表示 k 是否在 map 中

	fmt.Println("Deleting values")
	name, ok := m["name"]
	fmt.Println(name, ok)
	delete(m, "name")
	name, ok = m["name"]
	fmt.Println(name, ok)

	/*
		map 中的 key: 什么样的类型可以作为 key?
		- map 使用 hash, 必须比较相等;
		- 除了 slice/map/function 的内建类型都可以作为 key
		- Struct 类型只要不包含上述字段就可以作为 key, 编译时会检查
	*/
}


网站公告

今日签到

点亮在社区的每一天
去签到