前面我们学习了Go语言中的数组,切片类型。但是我们发现使用数组或切片存储的数据量如果比较大,那么通过下标来取出某个具体数据的时候,相对来说比较麻烦。
我们在数组或是切片中取值时,往往需要遍历这个数组或切片。比较麻烦。
那么有没有一种数据结构,能够帮我们快速的取出数据呢?那就Map结构,也就是字典结构。
Go语言中的结构是由键和值构成的,与其他语言类似。以键值对的形式存在。
某个键(key)都对应的一个值(value),如果要查询某个值,直接根据对应的键就可以查询出该值。
注意,这里,键不能重复。必须唯一。
一、map的定义与初始化
package main
import "fmt"
func main() {
//Map定义与使用
//字典名 map[ keyType ] valueType
var m map[int] string
m = make(map[int] string, 1)
// map [key] key是一个基本数据类型。
// map 是自动扩容的。
m[1] = "啦啦啦"
m[2] = "哈哈哈"
fmt.Println(m)
}
结果:
map[1:啦啦啦 2:哈哈哈]
这里我们在创建的时候,创建了一个长度的map,但是你会发现,我们在给map中添加数据的时候,一样可以添加进去。
这是因为,map这种数据结构,在go语言中,长度 是自动扩容的,并且两者始终保持相等。
这里还要说一下,键的类型,必须是支持==和!=操作符的类型,切片、函数以及包含切片的结构类型不能作为字典的键,使用这些类型会造成编译错误。
Map中的数据,是无序存储的。
package main
import "fmt"
func main() {
//Map定义与使用
//字典名 map[ keyType ] valueType
var m map[int] string
m = make(map[int] string, 1)
// map [key] key是一个基本数据类型。
// map 是自动扩容的。
m[1] = "啦啦啦"
m[2] = "哈哈哈"
m[3] = "哦哦哦"
m[4] = "啪啪啪"
fmt.Println(m)
//map中的值
for k, v := range m{
fmt.Println(k,v)
}
}
结果:
map[1:啦啦啦 2:哈哈哈 3:哦哦哦 4:啪啪啪]
1 啦啦啦
2 哈哈哈
3 哦哦哦
4 啪啪啪
Map在定义时需要注意,key是唯一的。另外一种定义方式:
package main
import "fmt"
func main() {
m:= map[string] int {"哈哈": 1, "啦啦": 2, "啪啪": 3}
fmt.Println(m)
}
结果:
map[哈哈:1 啦啦:2 啪啪:3]
二、Map中的值:
map中的值,可以直接循环打印,上面我们已经演示过了。
还可以直接通过键输出值:
package main
import "fmt"
func main() {
m:= map[string] int {"哈哈": 1, "啦啦": 2, "啪啪": 3}
fmt.Println(m["哈哈"])
}
结果:
1
如果在打印中,打印了没有出现的值,那么默认为空。
判断键值是否在map中,如果存在,则打印对应的值,如果不存在,就打印key值不存在
package main
import "fmt"
func main() {
m:= map[string] int {"哈哈": 1000, "啦啦": 2000, "啪啪": 3000}
//判断
v,ok := m["哈哈"]
if ok{
fmt.Println(v)
}else {
fmt.Println("key值不存在")
}
}
输出结果:
1000
三、删除Map中的元素
delete(map,key)
package main
import "fmt"
func main() {
m:= map[int] string {1:"111", 2:"222", 3:"333", 4:"444"}
//打印map m 的对应类型 复合类型
fmt.Printf("%T \n", m)
//删除元素
delete(m, 1)
fmt.Println(m)
}
打印结果:
map[int]string
map[2:222 3:333 4:444]
这里注意一下,我们在删除元素的时候,如果key不存在,也不会报错。
delete(map,key),删除操作,没有返回值。删除也不会影响map顺序。因为本身map就是无序的
四、Map作为函数参数
map作为函数参数进行,传递,是地址传递,也叫引用传递
package main
import "fmt"
func map_add(m map[int]string){
m[2] = "222"
}
func main() {
m:=make(map[int]string,1)
m[1] = "111"
//map 作为函数参数,是地址传递 (引用传递)
map_add(m)
fmt.Println(m)
}
结果:
map[1:111 2:222]
map可以在函数中添加数据,影响主调函数中实参的值
map只有长度值,没有容量值,只能用len()求得长度,不能用cap()求容量。cap在切片中使用。
特殊用法:
m:=make(map[int][]int)
上述这种用法,是map定义key值为int类型。value值为切片。
m:=make(map[int][]struct)
上述这种用法,是map定义key值为int类型。value值为结构体类型。