map

mapmapkey-value
var m变量名 map[关键字类型type] 指定值类型type
keymapkeykey==
valuekeymap

map声明举例:

var a map[string]string //key类型string value类型 string
var a map[string]int
var a map[int]string
var a map[int]map[string]int// key类型int value类型map[string]int 
//map可以包含多重map
mapmakeslicemapkeyvaluekeyvaluemapkey-value
func main() {
	//map的声明和注意事项
	var a map[string]string
	//在使用map必须使用make,给map分配数据空间
	fmt.Println(a) // nil map[]
	a = make(map[string]string, 10)

	//map 赋值操作
	a["no.1"] = "宋江"
	a["no.2"] = "吴用"
	fmt.Println(a) //map[no.1:宋江 no.2:吴用]

	//关键字不可重复
	a["no.1"] = "武松"
	fmt.Println(a) //map[no.1:武松 no.2:吴用]

	//value 可以相同
	a["no.3"] = "吴用"
	fmt.Println(a) //map[no.1:武松 no.2:吴用 no.3:吴用]

	a["no.4"] = "鲁智深"
	a["no.5"] = "晁盖"
	a["no.6"] = "孙二娘"

	//Golang的map的key-value 是遍历是无序的
	for i, v := range a {
		fmt.Printf("%v元素是%v\n", i, v)

	}
	/*
		no.2元素是吴用
		no.3元素是吴用
		no.1元素是武松
		no.4元素是鲁智深
		no.5元素是晁盖
		no.6元素是孙二娘*/
}

map的使用方式:

	var a map[string]string
	//在使用map必须使用make,给map分配数据空间
	a = make(map[string]string, 10)
	//map 赋值操作
	a["no.1"] = "宋江"
	a["no.2"] = "吴用"
	fmt.Println(a) //map[no.1:宋江 no.2:吴用]

	//第二种方式 类型推导
	cite := make(map[string]string, 10)
	cite["no.1"] = "北京"
	cite["no.2"] = "南京"
	cite["no.2"] = "武汉"
	fmt.Println(cite) //map[no.1:北京 no.2:武汉]

	//第三种形式  类型推导 +直接使用
	hero := map[string]string{
		"hero1": "武松",
		"hero2": "卢俊义", // 最后一行也必须有“,”
	}
	fmt.Println(hero) //map[hero1:武松 hero2:卢俊义]

使用案例
要求:
演示一个 key-value 的valeu是map类型的案例
要求:存放三个学生的信息,每个学生有学号 、name 和sex等信息

studentMap := make(map[string]map[string]string)

	//value是map类型的,还需进行make,才能使其分配空间,进行赋值操作
	studentMap["01234"] = make(map[string]string, 3)
	studentMap["01234"]["name"] = "tom"
	studentMap["01234"]["sex"] = "male"
	studentMap["01234"]["address"] = "武汉天地~"

	studentMap["01235"] = make(map[string]string, 3)
	studentMap["01235"]["name"] = "marry"
	studentMap["01235"]["sex"] = "female"
	studentMap["01235"]["address"] = "武汉天地~"

	studentMap["01236"] = make(map[string]string, 3)
	studentMap["01236"]["name"] = "Jay"
	studentMap["01236"]["sex"] = "male"
	studentMap["01236"]["address"] = "武汉天地~"

	fmt.Println(studentMap)
	fmt.Println(studentMap["01234"]) //map[address:武汉天地~ name:tom sex:male]
	fmt.Println(studentMap["01234"]["name"]) //tom
map["key"] = vlauekeykey
	cite := make(map[string]string, 10)
	cite["no.1"] = "北京" //如果没有no.1这个key,就是增加
	cite["no.2"] = "南京" //如果没有no.2这个key,就是增加
	fmt.Println(cite)   //map[no.1:北京 no.2:南京]
	cite["no.2"] = "武汉" //如果有no.2这个key,就是修改
	fmt.Println(cite)   //map[no.1:北京 no.2:武汉]
}
deletedelete(map,"key")keykey-valuekey

这里是引用

	//演示删除
	delete(cite, "no.1")
	fmt.Println(cite) // map[no.2:武汉]
	//当delete指定的key不存在时,不进行删除操作,但也不会报错
	delete(cite, "no.4")
	fmt.Println(cite) // map[no.2:武汉]

map = make(...)
// 一次性删除所有的key
	// 1.遍历所有的key,逐一删除
	heroname := map[string]string{
		"hero1": "武松",
		"hero2": "九纹龙",
		"hero3": "黑旋风",
	}
	fmt.Println(heroname)     //map[hero1:武松 hero2:九纹龙 hero3:黑旋风]
	for k,_:= range heroname { //map的遍历支持遍历key,也可写成 k:= range heroname
		delete(heroname, k)
	} 
	fmt.Println(heroname) //map[]

	//2.直接make一个新空间
	heroname1 := map[string]string{
		"hero1": "武松",
		"hero2": "九纹龙",
	}
	fmt.Println(heroname1) //map[hero1:武松 hero2:九纹龙]
	heroname1 = make(map[string]string)
	fmt.Println(heroname1) //map[]

mapkeyval,judge := m[key1]valmjudgeboolmkey1val = m[key1]truemkey1false

案例演示:

	movieName := make(map[string]string)
	movieName["American"] = "Revenger"
	movieName["Chinese"] = "满城尽带黄金甲"
	//map的查找
	// 如果movieName映射中存在key"Chinese",则把key"Chinese"对应的值赋给val,给judge赋值为true
	//否则judge 为 false
	val, judeg := movieName["Chinese"]

	if judeg {
		fmt.Printf("movieName映射中含义key:Chinese,对应的值为%v", val)
	} else {
		fmt.Println("movieName映射中不含义key:Chinese")

	}

}

Output:
movieName映射中含义key:Chinese,对应的值为满城尽带黄金甲

mapfor-rangemapvaluemapfor-range

案例演示:

ctiesName := make(map[string]map[string]string)
	ctiesName["武汉"] = map[string]string{
		"省份": "湖北",
		"车牌": "鄂A",
		"景点": "黄鹤.楼....",
	}

	ctiesName["北京"] = make(map[string]string)
	ctiesName["北京"]["省份"] = "直辖市"
	ctiesName["北京"]["车牌"] = "京牌"
	ctiesName["北京"]["景点"] = "天安门..."

	//map 的遍历
	// 使用for—range结构,遍历所得是键key 和 值value。(map是无序的故不可遍历得下标)
	for k1, v1 := range ctiesName {
		fmt.Println("k1=", k1)
		for k2, v2 := range v1 {
			fmt.Printf("\t k2=%v,对应的值v2=%v\n", k2, v2)
		}
	}

Output:
k1= 武汉
k2=景点,对应的值v2=黄鹤楼…
k2=省份,对应的值v2=湖北
k2=车牌,对应的值v2=鄂A
k1= 北京
k2=省份,对应的值v2=直辖市
k2=车牌,对应的值v2=京牌
k2=景点,对应的值v2=天安门…


len()

map切片

maps:=make([]map[type1]type)

案例演示:

要求使用一个map来记录monster的信息(name和age),即monster的value是一个map类型,并且怪兽的个数可动态增加(map切片)。

//map切片的使用
	//1.声明一个map切片
	mapSlice := make([]map[string]string, 2) //准备放入两个妖怪
	//增加妖怪的信息
	if mapSlice[0] == nil {

		mapSlice[0] = make(map[string]string)
		mapSlice[0]["name"] = "牛魔王"
		mapSlice[0]["age"] = "1000岁"
	}
	if mapSlice[1] == nil {
		mapSlice[1] = make(map[string]string)
		mapSlice[1]["name"] = "猪八戒"
		mapSlice[1]["age"] = "990岁"
	}
	fmt.Println(mapSlice) //[map[age:1000岁 name:牛魔王] map[age:990岁 name:猪八戒]]

	//切片定义长度后,切片包含元素不能超过其长度(未定义容易情况下)
	//下面操作会报错,越界。
	// if mapSlice[2] == nil {
	// 	mapSlice[2] = make(map[string]string)
	// 	mapSlice[2]["name"] = "蜘蛛精"
	// 	mapSlice[2]["age"] = "999岁"
	// }

	//使用切片的动态append函数,可动态增加monster的
	//1.新建一个monster信息
	monster := map[string]string{
		"name": "金角大王",
		"age":  "1000岁",
	}
	mapSlice = append(mapSlice, monster)
	fmt.Println(mapSlice)
	//[map[age:1000岁 name:牛魔王] map[age:990岁 name:猪八戒] map[age:1000岁 name:金角大王]]

	// 2.直接增加map内容
	mapSlice = append(mapSlice, map[string]string{"name": "孙悟空", "age": "1500岁"})
	fmt.Println(mapSlice)
	// [map[age:1000岁 name:牛魔王] map[age:990岁 name:猪八戒] map[age:1000岁 name:金角大王] map[age:1500岁 name:孙悟空]]

	fmt.Println(mapSlice[2], mapSlice[3]) //map[age:1000岁 name:金角大王] map[age:1500岁 name:孙悟空]

Noting:
1)map的使用时,在声明\定义时,未定义长度\定义了长度情况下都是可以无限创建key-value对的,即map映射会具有动态增加自身长度的功能。

	m := make(map[int]string, 2)
	m[1] = "abc"
	m[2] = "abcd"
	fmt.Println(m)      //map[1:abc 2:abcd]
	fmt.Println(len(m)) //2
	//再增加一个关联数组则也不会报错
	m[3] = "bcd"
	fmt.Println(m)      //map[1:abc 2:abcd 3:bcd]
	fmt.Println(len(m)) //3
mapmapmapappend
	monster := map[string]string{
			"name": "金角大王",
			"age":  "1000岁",
		}
	//2)
	//noting
	//不可对已存在的`map`映射直接进行切片处理,因为`map`本质上键值对集合是无序的。
	//下面操作报错,不可对map进行切片	
	// mapSlice02 := monster[:]
	//3)
	mapSlice1 := make([]map[string]string, 0)
	mapSlice1 = append(mapSlice1, monster)
	fmt.Println(mapSlice1)//[map[age:1000岁 name:金角大王]]

sort
	m := make(map[int]string, 10)

	m[0] = "1"
	m[1] = "2"
	m[2] = "3"
	m[9] = "6"

	fmt.Println(m)

	for k, v := range m {
		fmt.Printf("key=%v,value=%v\n", k, v)
	} //输出结果是无序的

	// 要求按照map的key的顺序进行排序输出
	// 1.先将map的key放入到切片中
	// 2.对切片进行排序
	// 3.遍历切片,然后按照key来输出map的值

	var keys []int
	for k := range m {
		keys = append(keys, k)
	}

	//排序 升序
	sort.Ints(keys)
	fmt.Println(keys) //[0 1 2 9]

	for _, v := range keys {
		fmt.Printf("m[%v]=%v\n", v, m[v])
	}
	/* m[0] = 1
	   m[1] = 2
	   m[2] = 3
	   m[9] = 6 */
	fmt.Println()

	//排序 降序
	sort.Sort(sort.Reverse(sort.IntSlice(keys)))
	for _, v := range keys {
		fmt.Printf("m[%v]=%v\n", v, m[v])
	}
	/*m[9] = 6
	  m[2] = 3
	  m[1] = 2
	  m[0] = 1 */

map使用细节
1)map是引用类型,遵守引用类型地址传递机制(地址传递)。在一个函数接收map,修改后,会直接修改原来的map。

func modify(m map[int]int) {
	m[10] = 100
}
func main() {
	m := make(map[int]int)
	m[1] = 10
	m[2] = 130
	m[10] = 18
	m[20] = 119

	modify(m)
	fmt.Println(m)
	//map[1:10 2:130 10:100 20:119]  说明map是引用类型
valuestruct
type stuInfo struct {
	Name    string
	Age     int
	Sex     string
	Address string
}
func main() {
studenMap := make(map[string]stuInfo)

	//定义结构体 再赋值
	stu0 := stuInfo{Name: "Alex", Age: 18, Sex: "男", Address: "武汉"}
	stu1 := stuInfo{"Alice", 18, "女", "南京"}
	studenMap["1020"] = stu0
	studenMap["1021"] = stu1
	//直接赋值
	studenMap["1022"] = stuInfo{"Ming", 18, "男", "北京"}
	fmt.Println(studenMap)
	// map[1020:{Alex 18 男 武汉} 1021:{Alice 18 女 南京} 1022:{Ming 18 男 北京}]

	// 遍历形式
	for k, v := range studenMap {
		fmt.Printf("学生的学号是%v\n", k)
		fmt.Printf("\t学生的名字是%v\n", v.Name)
		fmt.Printf("\t学生的年龄是%v\n", v.Age)
		fmt.Printf("\t学生的性别是%v\n", v.Sex)
		fmt.Printf("\t学生的地址是%v\n", v.Address)
		fmt.Println()
	}
	/*	学生的学号是1020
	        学生的名字是Alex
	        学生的年龄是18
	        学生的性别是男
	        学生的地址是武汉
	        ....
}