go map

go map 特性

1、map常规操作。

Map存储的是无序的键值对集合 ,引⽤类型,哈希表。键必须是⽀持相等运算符 (==、!=) 类型,⽐如 number、string、pointer、array、struct,以及对应的 interface。值可以是任意类型,没有限制。

示例:

unc test1() {
	// 1、初始化
	m1 := make(map[int]string, 1000)	// 1000表示map最多能存放的key_value的数量,超过后,需要重新分配内存

	m2 := map[string]int{
		"a": 1,
	}

	// 2、判断 key 是否存在
	if val, ok := m2["a"]; ok {
		fmt.Println(val)
	}

	// 3、访问不存在的key
	fmt.Println(m2["b"]) //	返回value类型的默认初始值

	// 4、新增或修改
	m2["b"] = 1

	// 5、删除key
	delete(m2, "c") //	如果key不存在,不会出错

	// 6、获取键值对的数量
	fmt.Println(len(m1)) //	cap无效

	// 7、遍历
	for k, v := range m2 {
		fmt.Println(k, v) //	随机顺序返回,每次都不相同
	}

	for k := range m2 {
		fmt.Println(k)
	}

	for _, v := range m2 {
		fmt.Println(v)
	}

}

2、怎样顺序遍历map?将key排序,然后根据key去找到value。

示例:

func test2() {
	m := make(map[string]int, 32)
	rand.Seed(time.Now().UnixNano())
	keySlice := []string{}

	for i := 0; i < 10; i++ {
		key := fmt.Sprintf("stu_%d", i)
		m[key] = rand.Intn(100)
		keySlice = append(keySlice, key)
	}

	fmt.Println("before sort, the map is:")
	for k, v := range m {
		fmt.Println(k, v)
	}

	fmt.Println("\nafter sort:")
	sort.Strings(keySlice)
	for _, v := range keySlice {
		fmt.Println(v, m[v])
	}
}

输出:

before sort, the map is:
stu_3 99
stu_4 34
stu_6 9
stu_9 92
stu_2 37
stu_8 92
stu_7 79
stu_0 88
stu_5 41
stu_1 69

after sort:
stu_0 88
stu_1 69
stu_2 37
stu_3 99
stu_4 34
stu_5 41
stu_6 9
stu_7 79
stu_8 92
stu_9 92

3、从 map 中取回的是⼀个 value 临时复制品,对其成员的修改是没有任何意义的。

示例:

type user struct{ name string }
m := map[int]user{        // 当 map 因扩张⽽重新哈希时,各键值项存储位置都会发⽣改变。因此,map
    1: {"user1"},         // 被设计成 not addressable。类似 m[1].name 这种期望透过原 value
}                         // 指针修改成员的⾏为⾃然会被禁⽌。
m[1].name = "Tom"         // Error: cannot assign to m[1].name

正确修改方式:

//	方法1
u := m[1]				//	m[1]返回一个值拷贝的结构体
u.name = "Tom"
m[1] = u                  // 替换 value。

//	方法2
m2 := map[int]*user{	 //	m2[1]返回指针拷贝
    1: &user{"user1"},
}
m2[1].name = "Jack"       // 返回的是指针复制品。透过指针修改原对象是允许的。

4、可以在迭代时安全删除键值。但如果期间有新增操作,就会出现异常。

示例:

func test3() {
	m := map[int]string{
		1: "zhou",
		2: "wu",
		3: "zheng",
		4: "wang",
	}
	fmt.Printf("before delete, the map is:%v\n", m)
	for k := range m {
		delete(m, k)
	}
	fmt.Printf("after delete, the map is:%v\n", m)

	m2 := map[int]string{
		1: "zhou",
		2: "wu",
		3: "zheng",
		4: "wang",
	}
	fmt.Printf("\nbefore delete, the m2 is:%v\n", m2)
	for k := range m2 {
		m2[k+k] = "add new"
		delete(m2, k)
	}
	fmt.Printf("after delete, the m2 is:%v\n", m2)
}

输出:

before delete, the map is:map[1:zhou 2:wu 3:zheng 4:wang]
after delete, the map is:map[]

before delete, the m2 is:map[1:zhou 2:wu 3:zheng 4:wang]
after delete, the m2 is:map[4:add new 6:add new 16:add new]

5、 map_slice、 slice_map

示例:


func sliceMap() {
	s := make([]map[string]int, 4)
	s[0] = make(map[string]int, 16)
	s[0]["stu_01"] = 50
	s[0]["stu_02"] = 60
	s[0]["stu_01"] = 70

	for i, v := range s {
		fmt.Printf("s[%d] = %#v\n", i, v)
	}
}

func mapSlice() {
	m := make(map[string][]int, 4)
	key := "stu_01"
	if _, ok := m[key]; !ok {
		m[key] = make([]int, 0, 8)
	}

	m[key] = append(m[key], 100)
	m[key] = append(m[key], 200)
	m[key] = append(m[key], 300)

	for k, v := range m {
		fmt.Println(k, v)
	}
}

输出:

s[0] = map[string]int{"stu_01":70, "stu_02":60}
s[1] = map[string]int(nil)
s[2] = map[string]int(nil)
s[3] = map[string]int(nil)
stu_01 [100 200 300]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值