[go语言]map类型

map类型

go语言利用hash表来实现,它是一个无序的key/value的集合,key唯一并且必须支持“==”运算符进行比较。

定义

var 变量名 map[key类型]value类型,由于map是一个引用类型,必须初始化才可以使用,对于切片来说,使用append函数会去分配内存空间,所以可以使用。

var map1 map[string]int
map1["nihao"] = 100
println(map1)

输出:

panic: assignment to entry in nil map [recovered]

map初始化

  • 使用make函数
    map1 := make(map[string]int)
map1 := make(map[string]int)
map1["nihao"] = 100
fmt.Println(map1)

输出:

map[nihao:100]
  • 定义时初始化
    map1 := map[string]int{key:value,key:value}

其中“{}”内容可以为空,这时创建了一个内容空的map,并非nil。

map1 := map[string]int{
    "nihao": 100,
    "hello": 20,
}
fmt.Println(map1)

输出:

map[hello:20 nihao:100]

注意:这个时候只能使用:=声明,不能使用var声明。

map元素不可取地址

map中的元素并不是一个变量,所以是不可以对map中的元素进行取地址操作。

map1 := map[string]int{}
map1["张三"] = 90

var a = &map1["张三"]//invalid operation: cannot take address of map1["张三"]

不能对map取地址的原因是map可能随元素的增加而重新分配内存空间,从而导致之前的地址无效。

map基本操作

获取元素(判断元素是否存在)

map使用key作为索引获取元素。

value, ok := map1["nihao"]
value := map1["nihao"]

如果存在ok等于true,value等于对应的值,不存在则ok为false,value为对应类型的零值,其中ok可以省略不写。

获取元素个数

map可以使用len函数来获取元素个数,如果map为nil或元素为空时,len等于0。

var map1 map[string]int
fmt.Println(len(map1))

添加修改

如果存在则修改,不存在则添加。

map1["nihao"] = 100

在map中支持x+=yx++语法。

map1["nihao"] = map1["nihao"] +1

可以写成
map1["nihao"] ++map1["nihao"] += 1

删除

delete 内置函数用于删除map指定键的元素,如果map为nil或不存在这样的元素,则删除是一个空操作。

delete(map1,"nihao")

遍历

map是通过key作为索引,所以只能使用for range进行遍历,其中value可以省略的,这时只获取map的key。

map1 := map[string]int{}
map1["张三"] = 90
map1["小明"] = 100
map1["娜扎"] = 60
for k, v := range map1 {
    fmt.Println(k, v)
}

输出:

小明 100
娜扎 60
张三 90

按照顺序进行遍历

map是无序存储的,而且每次遍历的顺序都是随机的,如果想要顺序遍历,可以将key放到切片中,随后对切片进行排序,通过排好序的切片访问map。

map1 := map[string]int{}
map1["张三"] = 90
map1["小明"] = 100
map1["娜扎"] = 60
keySlice := make([]string, 0)

for k := range map1 {
    keySlice = append(keySlice, k)
}

sort.Strings(keySlice)

fmt.Println(keySlice)
for _, key := range keySlice {
    fmt.Println(key, map1[key])
}

判断两个map是否相等

如同切片一样,map之间是不可以之间比较的,但是可以跟nil比较。如果想要判断两个map是否相等,可以使用循环的方式进行判断。

func equal(x, y map[string]int) bool {
	if len(x) != len(y) {
		return false
	}

	for k1, v1 := range x {
		if v2, ok2 := y[k1]; !ok2 || v1 != v2 {
			return false
		}
	}

	return true
}

利用map实现set

go语言中没有set数据结构,但是我们可以使用map来实现set。

map1 := map[string]bool{}
map1["张三"] = true
map1["小明"] = true
map1["娜扎"] = true

if !map1["nihao"] {
    map1["nihao"] = true
}
fmt.Println(map1)

输出:

map[nihao:true 娜扎:true 小明:true 张三:true]

利用辅助函数设置不可比较的key

map中的key是必须能够使用”==“比较的,如果需要存储不能比较的数据,我们可以利用辅助函数将key转化为可以比较的数据。

func TestMap10(t *testing.T) {
	a1 := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
	s1 := a1[:5]
	s2 := a1[:8]

	map1 := map[string]bool{
		k(s1): false,
		k(s2): false,
	}

	fmt.Println(map1)
}

func k(list []int) string {
	return fmt.Sprint(list)
}

输出:

map[[1 2 3 4 5 6 7 8]:false [1 2 3 4 5]:false]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值