Go语言12-复合类型-字典

 

1.字典概述

Go语言中的map(映射、字典)是一种内置的数据结构,它是一个无序的键值对(key:value)集合,key类似于索引,可以通过key快速检索value。

Go语言12-复合类型-字典_第1张图片

 

2.字典的声明和初始化

2.1字典的声明

var m1 map[keyType]valueType

a.一个map里所有的键都是唯一的。

b.所有的键必须支持“==”和“!=”操作符的类型,切片、函数以及包含切片的结构体,因为具有引用语义,不能作为键,使用这些类型会造成编译错误。

c.map值可以是任意类型,没有 限制。

d.map里所有键的数据类型必须是相同的,值的数据类型也必须相同,但键和值的数据类型可以不相同。

e.因为map使用的hash表来实现的,所以map是无序的,无法决定他们的返回顺序。所以每次打印结果顺序有可能不同。

2.2空字典

仅仅声明、而没有初始化的字典为空字典。空字典是不能存储键值对的。

package main

import "fmt"

func main() {
	var m1 map[int]string
	fmt.Println(m1) //仅声明的字典是空字典,打印结果m1=map[]
	fmt.Println(m1 == nil)
	m1[1] = "a"
	fmt.Println(m1) //空字典是不能存储键值对的,程序出现panic错误
}

程序运行结果:

map[]
true
panic: assignment to entry in nil map

goroutine 1 [running]:
main.main()

2.3字典初始化

方式 示例
先声明,再初始化 var m1 map[int]string
m1 = map[int]string{}//打印结果为map[],非空字典
var m2 map[int]string
m2 = map[int]string{1: "mike", 2: "yoyo"}
声明的同时初始化 var m3 map[int]string = map[int]string{1: "mike", 2: "yoyo"}
自动推导类型初始化 var m4 = map[int]string{1: "mike", 2: "yoyo"}
m5 := map[int]string{1: "mike", 2: "yoyo"}
通过make()函数创建 m6 := make(map[int]string, 10) //打印结果为map[],非空字典

map超出容量时会自动扩容。

3.字典的操作

3.1赋值

a.对已存在的键值赋值:相当于对已知键值对进行修改。

b.添加不存在的键值对:前提是字典完成过初始化

mapName[key] = value
package main

import "fmt"

func main() {
	m := map[int]string{1: "mike", 2: "yoyo"}
	/*对已经存在的键值赋值*/
	m[1] = "Wei Xiaobao"
	fmt.Println("m =", m)
	/*添加不存在的键值对*/
	m[3] = "Zhang Sanfeng"
	fmt.Println("m =", m)
}

运行结果:

3.2 遍历

方式1:

for k,v :=range mapName{
    fmt.Printf("%v:%v\n",k,v) //%v:以默认模式输出,输出格式:“key: value”
}

方式2:

for k :=range mapName{
    fmt.Printf("%v:%v\n", k, mapName[k]) //mapName[k]:通过键k得到对应的value
}

方式3:

for _,v := range mapName{
    fmt.Printf("v = %v\n",v) //不能通过v得到key值,只能通过键获取值,不能通过值获取键
}
package main

import "fmt"

func main() {
	m := map[int]string{1: "mike", 2: "yoyo"}
	fmt.Println("方式1:")
	for k, v := range m { //返回key和value
		fmt.Printf("\t%v:%v\n", k, v) //%t :表示一个tab键
	}
	fmt.Println("方式2:")
	for k := range m { //仅返回key
		fmt.Printf("\t%v:%v\n", k, m[k]) //mapName[k]: 通过k再去得到对应的value
	}
	fmt.Println("方式3:")
	for _, v := range m { //仅返回value,_站位,表示忽略这个位置的返回值
		fmt.Printf("\tv=%v\n", v)
	}
}

3.3查询

方式1:

value, ok := mapName[key] //ok的结果有两种:true或false
if ok{ //如果ok为true,执行括号内代码
    /*处理找到的值*/
}

方式2:

//ok为true或或false,如果ok为true,执行括号内代码
if value, ok := mapName[key];ok{
    /*处理找到的value*/
}
package main

import "fmt"

func main() {
	m := map[int]string{1: "mike", 2: "yoyo"}
	value1, ok := m[1] //ok 两种结果:true或false
	if ok {
		//如果ok为true,执行代码
		fmt.Printf("找到了:key = 1, value = %v\n", value1)
	}
	value2, ok := m[3]
	if ok {
		//如果ok为true,执行代码
		fmt.Printf("找到了:key = 3, value = %v\n", value2)
	} else {
		//如果ok为false,执行代码
		fmt.Printf("没有找到!\n")
	}
}

3.4删除键值对

delete(mapName, key)

a.key只能是一个,不能是多个,即每次只能删除一个元素

b.如果这个key不存在,则这个函数将什么都不发生。

package main

import "fmt"

func main() {
	m := map[int]string{1: "mike", 2: "yoyo", 3: "Zhang Sanfeng"}
	fmt.Println(m)
	delete(m, 1) //删除key为1的键值对
	fmt.Println(m)
	delete(m, 4) //4不是字典的键,删除key为4的键值对,没有任何改变
	fmt.Println(m)
}

4 字典作为函数参数

字典变量作为函数参数,再函数间传递的是引用传递,不是值传递。

package main

import "fmt"

func main() {
	m := map[int]string{1: "mike", 2: "yoyo", 3: "lily"}
	fmt.Println("主函数(删除前): ")
	fmt.Println("\tm =", m)
	deleteMap(m, 2) //调用函数
	fmt.Println("主函数(删除后): ")
	fmt.Printf("\tm=%v, len(m)=%d\n", m, len(m))
	for k, v := range m {
		fmt.Printf("\tk = %d ----> v = %s\n", k, v)
	}
}

func deleteMap(m map[int]string, key int) {

	delete(m, key) //删除key为2的键值对
	fmt.Println("自定义函数:")
	fmt.Printf("\tm = %v, len(m)=%d\n", m, len(m))
	for k, v := range m {
		fmt.Printf("\tk = %d ----> v = %s\n", k, v)
	}
}

 

你可能感兴趣的:(GO)