map是一种key-value
数据结构,类似于其它的编程语言,如Java。
//基本语法
var map 变量名 map[keytype]valuetype
map中的key可以是很多种类型,如bool,数字,string,指针,channel,还可以是接口,结构体,数组。
但是key不可以是slice、map还有function,因为这三个类型无法用 == 来判断。
value的类型和key的基本一致。
例子
var am map[string]string
var am map[string]int
var am map[int]string
var am map[string]map[string]string
声明是不会分配内存的,还需要初始化,这时要用到make,分配内存后才能赋值和使用。
func main(){
//声明一个map
var am map[string]string
//对map进行初始化
am = make(map[string]string, 10)
am["AA"] = "am"
am["BB"] = "bm"
am["CC"] = "cm"
fmt.Println(am)
}
注意:
- map在使用前要make初始化
- map的key是不能重复的,若重复了,以最后的那个值为准
- map是value可以重复的
- map的key-value是无序的
//用法一
var am map[string]string
am = make(map[string]string, 10)
am["AA"] = "am"
am["BB"] = "bm"
am["CC"] = "cm"
fmt.Println(am)
//用法二
am := make(map[string]string)
am["AA"] = "am"
am["BB"] = "bm"
am["CC"] = "cm"
fmt.Println(am)
//用法三
am := map[string]string{
"AA" : "am",
"BB" : "bm",
"CC" : "cm",
}
am["DD"] = "dm"
fmt.Println(am)
当value是map类型的时候,怎么使用?
per := make(map[string]map[string]string)
per["jam"] = make(map[string]string, 3)
per["jam"]["age"] = "20"
per["jam"]["sex"] = "男"
per["jam"]["addr"] = "aaa"
per["lily"] = make(map[string]string, 3)
per["lily"]["age"] = "30"
per["lily"]["sex"] = "女"
per["lily"]["addr"] = "ccc"
fmt.Println(per)
fmt.Println(per["jam"])
fmt.Println(per["jam"]["addr"])
map的增加和修改都是使用
map["key"] = value
//如果key是不存在的,该操作就是增加;如果key是存在的,该操作就是修改。
map的删除
delete(map, "key")
//delete是一个内置函数,如果key存在,就直接删除该key的value;如果没有key,不操作也不会报错
am := make(map[string]string)
am["AA"] = "am"
am["BB"] = "bm"
am["CC"] = "cm"
fmt.Println(am)
delete(am,"AA")
fmt.Println(am)
//key不存在也不会报错
delete(am,"DD")
fmt.Println(am)
如果要删除map里面所有的key,是要进行遍历一下key进行删除的;
或者用 map=make(…),make一个新的,让原来的成为垃圾,被gc回收。
map的查找
val, ok := am["AA"]
if ok {
fmt.Printf("有AA,值为%v\n", val)
} else {
fmt.Printf("没有AA")
}
如果am中存在"AA"这个key,就会返回true,否则返回false。
这里使用for-range的结构进行遍历
func main(){
am := make(map[string]string)
am["AA"] = "am"
am["BB"] = "bm"
am["CC"] = "cm"
for k, v := range am{
fmt.Printf("k=%v v=%v\n", k, v)
}
//遍历复杂的map
pm := make(map[string]map[string]string)
pm["jam"] = make(map[string]string, 3)
pm["jam"]["age"] = "20"
pm["jam"]["sex"] = "男"
pm["jam"]["addr"] = "aaa"
pm["lily"] = make(map[string]string, 3)
pm["lily"]["age"] = "30"
pm["lily"]["sex"] = "女"
pm["lily"]["addr"] = "ccc"
for k1, v1 := range pm{
fmt.Println("k1=",k1)
for k2, v2 := range v1{
fmt.Printf("\t k2=%v v2=%v\n", k2, v2)
}
fmt.Println()
}
}
//其方法是
func len(v Type) int
内建函数len返回v的长度,这取决于具体类型:
数组:v中元素的数量
数组指针:*v中元素的数量(v为nil是panic)
切片、映射:v中元素的数量;若v为nil,len(v)即为零
字符串:v中字节的数量
通道:通道缓存中队列(未读取)元素的数量;若v为nil,len(v)为零。
例子:
fmt.Println(len(pm))
切片的数据类型如果是map,那就是map切片,这样map的个数就可以动态变化了。
func main(){
//这里先声明一个map切片,即该切片存储的数据类型是map
//该map主要记录一个人物信息,name和age
var per []map[string]string
//存放人物信息
per = make([]map[string]string, 2)
if per[0] == nil {
per[0] = make(map[string]string, 2)
per[0]["name"] = "jam"
per[0]["age"] = "14"
}
if per[1] == nil {
per[1] = make(map[string]string, 2)
per[1]["name"] = "lily"
per[1]["age"] = "20"
}
//这时候使用切片的append函数进行追加,动态增加一个per信息
newper := map[string]string{
"name" : "ami"
"age" : "27"
}
per = append(per, newper)
fmt.Println(per)
}
golang是没有一种方法是可以对map的key进行排序的,因为map默认是无序的,即使你按照一定顺序存放,每次遍历得出来的顺序结果都不一样。
func main(){
mape := make(map[int]int, 5)
mape[5] = 4
mape[2] = 55
mape[1] = 21
fmt.Println(mape)
}
如果想按照map的key的顺序进行排序输出,可增加
var keys []int
for k,_ := range mape {
keys = append(keys, k)
}
//排序
sort.Ints(keys)
//输出排序后key的值
for _, k := range keys{
fmt.Printf("mape[%v]=%v \n", k, mape[k])
}
func update(mape map[int]int){
mape[2] = 30
}
func main(){
mape := make(map[int]int)
mape[1] = 2
mape[2] = 4
mape[10] = 100
update(mape)
fmt.Println(mape)
}