go-map

go-map

介绍

  1. map是key-value数据结构,又称为字段或者关联数组。类似其他编程语言的集合。

  2. 基本语法 : var map变量名 map[keyType]valueType

    keyType:golang中的map的key可以是很多种类型:bool、数字、string、指针、channel、还可以是只包含前面几个类型的接口、结构体、数组

    通常是int和string

  3. slice,map还有function不可以,因为这几个没法用==来判断

  4. valueType的类型和key基本相似

    通常是数字、string、map、struct

  5. map使用签一定要make分配空间

  6. map的key不能重复,若重复,则会覆盖

  7. map的value可以重复

  8. map的key-value无序

  9. make
    映射:初始分配的创建取决于size,但产生的映射长度为0。size可以省略,这种情况下就会分配一个
         小的起始大小。
    
func main() {
	var map1 map[string]int = make(map[string]int) // 需make分配空间,否则无法使用
	fmt.Printf("map1: %v\n", map1)                 // map1: map[]
	fmt.Printf("&map1: %p\n", &map1)               // &map1: 0xc0000b6010
	map1["tom"] = 22
	map1["jack"] = 33
	map1["tom"] = 33
	fmt.Printf("map1: %v\n", map1) // map1: map[jack:33 tom:33]  key不重复,且无序
}

三种用法

  1. 先声明再make
  2. 既声明也make
  3. 声明+赋值
func main() {
	// 1. 先声明再赋值
	var map1 map[string]int
	map1 = make(map[string]int)
	map1["tom"] = 22
	map1["jack"] = 33
	fmt.Printf("map1: %v\n", map1) // map1: map[jack:33 tom:22]

	// 2. 声明+make
	var map2 map[string]int = make(map[string]int)
	map2["beijing"] = 1
	map2["shanghai"] = 2
	map2["dalian"] = 5
	fmt.Printf("map2: %v\n", map2) // map2: map[beijing:1 dalian:5 shanghai:2]

	// 3. 声明+赋值
	var map3 map[string]int = map[string]int{
		"beijing":  1,
		"shanghai": 2,
		"shenzhen": 3, // , 不能省
	}
	map3["xiongan"] = 4
	// map3 := map[string]int{"beijing": 1, "shanghai": 2, "shenzhen": 3}
	fmt.Printf("map3: %v\n", map3) // map3: map[beijing:1 shanghai:2 shenzhen:3 xiongan:4]

}


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

	studentMap["student1"] = make(map[string]string)
	studentMap["student1"]["name"] = "tom"
	studentMap["student1"]["sex"] = "man"
	studentMap["student1"]["address"] = "beijing"
	studentMap["student1"]["tel"] = "123456789"

	studentMap["student2"] = make(map[string]string)
	studentMap["student2"]["name"] = "jack"
	studentMap["student2"]["sex"] = "women"
	studentMap["student2"]["address"] = "shanghai"
	studentMap["student2"]["tel"] = "123123123"

	fmt.Printf("studentMap: %v\n", studentMap)
	fmt.Printf("studentMap[\"student1\"]: %v\n", studentMap["student1"])
	fmt.Printf("studentMap[\"student2\"]: %v\n", studentMap["student2"])
	fmt.Printf("studentMap[\"student1\"][\"name\"]: %v\n", studentMap["student1"]["name"])

crud操作

func main() {
	var map1 map[string]int = make(map[string]int)
	// 1. 增加和修改
	// 1.1 添加  key不存在就是添加
	map1["tom"] = 22
	map1["jack"] = 33
	fmt.Printf("map1: %v\n", map1) // map1: map[jack:33 tom:22]
	// 1.2 修改  key存在就是添加
	map1["jack"] = 66
	fmt.Printf("map1: %v\n", map1) // map1: map[jack:66 tom:22]

	// 2. 删除  内置函数delete(map, key)
	delete(map1, "tom")
	fmt.Printf("map1: %v\n", map1) // map1: map[jack:66]
	delete(map1, "tom")            // 当不存在时,也不会报错

	// 3. 清空map
	// 3.1 遍历逐个删除
	for k := range map1 {
		delete(map1, k)
	}
	// 3.2 直接给map开辟一个新空间, make
	map1 = make(map[string]int)

	// 4. 查找  第一个返回值是 对应的值value,   第二返回值是,是否找到,若找到为true 否则为 false
	val, findres := map1["no"]
	if findres {
		fmt.Printf("val: %v\n", val)
	} else {
		fmt.Println("no find")
	}
}

遍历

func main() {
	// map遍历
	var people map[string]int = map[string]int{"tom": 22, "jack": 33, "luxy": 44}
	// 1. 整体遍历
	for k, v := range people {
		fmt.Printf("%v: %v\t", k, v) // tom: 22  jack: 33  luxy: 44
	}
	fmt.Println("")

	// 2. 仅遍历key 和 获取key的切片
	keys := make([]string, 0, len(people))
	for k := range people {
		keys = append(keys, k)
		fmt.Printf("k: %v\n", k)
	}
	// k: tom
	// k: jack
	// k: luxy

	// 3. 内置函数len 获取map的长度
	fmt.Printf("len(people): %v\n", len(people)) // len(people): 3
}

切片

func main() {
	var people []map[string]string = make([]map[string]string, 1)
	var people1 map[string]string = make(map[string]string)
	people1["name"] = "tom"
	people1["age"] = "22"
	people1["address"] = "shanghai"
	people = append(people, people1)

	var people2 map[string]string = make(map[string]string)
	people2["name"] = "jack"
	people2["age"] = "33"
	people2["address"] = "beijing"
	people = append(people, people2)

	people[0] = make(map[string]string)
	people[0]["name"] = "lucy"
	people[0]["age"] = "44"
	people[0]["address"] = "shenzhen"

	// people: [map[address:shanghai age:22 name:tom] map[address:beijing age:33 name:jack]]
	fmt.Printf("people: %v\n", people)
	for index, val := range people {
		fmt.Printf("index: %v\n", index)
		// fmt.Printf("val: %v\n", val)
		for k, v := range val {
			fmt.Printf("\t %v: %v  \n", k, v)
		}
	}
	// index: 0        val: map[address:shanghai age:22 name:tom]
	// index: 1        val: map[address:beijing age:33 name:jack]

	/*
		index: 0
				age: 22
				address: shanghai
				name: tom
		index: 1
				name: jack
				age: 33
				address: beijing
	*/
}

排序

  1. golang中没有一个专门的方法针对map的key进行排序
  2. golang中的map默认是无序的,注意不是按照添加的顺序存放的,每次遍历得到的输出结果不同
  3. golang中的map排序,是先将key进行排序,然后根据key值遍历输入即可
import (
	"fmt"
	"sort"
)

func main() {
	var numMap map[int]int = make(map[int]int)
	numMap[3] = 33
	numMap[1] = 11
	numMap[4] = 44
	numMap[2] = 22
	numMap[5] = 55
	fmt.Printf("numMap: %v\n", numMap)
	// 1. 先将map的key放入到切片
	// 2. 对切片进行排序
	// 3. 遍历切片。按照key来输入map值
	keys := make([]int, 0, len(numMap))
	for k := range numMap {
		keys = append(keys, k)
	}

	sort.Ints(keys)
	fmt.Printf("keys: %v\n", keys) // keys: [1 2 3 4 5]

	for _, v := range keys {
		fmt.Printf("key: %v  value: %v\n", v, numMap[v])
		// key: 1  value: 11
		// key: 2  value: 22
		// key: 3  value: 33
		// key: 4  value: 44
		// key: 5  value: 55
	}
}

注意事项

  1. map是引用类型,遵守引用类型传递的机制,在一个函数接收map,修改后,会直接修改原来的map

    func main() {
    	map1 := make(map[int]int)
    	map1[1] = 11
    	map1[3] = 33
    	test(map1)
    	fmt.Printf("map1: %v\n", map1) // map1: map[1:111 2:222 3:33]
    }
    
    func test(map1 map[int]int) {
    	map1[1] = 111
    	map1[2] = 222
    }
    
  2. map的扩容达到后,再向map增加元素,会自动扩容,并不会发生panic,也就是说map能动态的增长键值对

  3. map的value也经常使用struct类型,更适合管理复杂的数据(比前面value是一个map更好),比如value是Student结构体

func main() {
	studentMap := make(map[int]student)
	studentMap[1] = student{"tom", 11, "beijing"}
	studentMap[2] = student{"jack", 22, "shanghai"}
	studentMap[3] = student{"lucy", 33, "shenzhen"}
	fmt.Printf("studentMap: %v\n", studentMap)

	for k, s := range studentMap {
		fmt.Printf("k: %v  ", k)
		fmt.Printf("s.name: %v  ", s.name)
		fmt.Printf("s.age: %v  ", s.age)
		fmt.Printf("s.address: %v\n", s.address)
	}
}

type student struct {
	name    string
	age     int
	address string
}

案例

func main() {
	var userMap map[string]map[string]string = make(map[string]map[string]string)
	name := "tom"
	modifyUser(userMap, name)
	fmt.Printf("userMap: %v\n", userMap)
	// userMap: map[tom:map[nickname:nickname pwd:123456]]

	modifyUser(userMap, name)
	fmt.Printf("userMap: %v\n", userMap)
	// userMap: map[tom:map[nickname:nickname pwd:888888]]
}

func modifyUser(users map[string]map[string]string, name string) {
	v, findres := users[name]
	if findres {
		v["pwd"] = "888888"
	} else {
		v = make(map[string]string)
		v["nickname"] = "nickname"
		v["pwd"] = "123456"
		users[name] = v
	}
}
在Go语言中,可以使用以下方式来查找map中的值: ```go val, ok := mapName\[key\] ``` 其中,`mapName`是你定义的map变量的名称,`key`是你要查找的键值。这个语法会返回两个值,`val`是对应键值的值,`ok`是一个布尔值,表示是否找到了对应的键值。如果找到了,`ok`的值为`true`,否则为`false`。 下面是一个示例代码: ```go package main import "fmt" func main() { cities := make(map\[string\]string) cities\["no1"\] = "北京" cities\["no2"\] = "上海" cities\["no3"\] = "广州" val, ok := cities\["no2"\] if ok { fmt.Printf("找到了,值为%v\n", val) // 输出:找到了,值为上海 } else { fmt.Println("没有找到") } } ``` 在这个示例中,我们定义了一个名为`cities`的map变量,并给它赋值。然后,我们使用`cities\["no2"\]`来查找键为`"no2"`的值。由于存在这个键,所以`ok`的值为`true`,并且将对应的值`"上海"`赋给了`val`。最后,我们根据`ok`的值来判断是否找到了对应的值,并进行相应的输出。 希望这个例子能够帮助你理解如何在Go语言中查找map的值。 #### 引用[.reference_title] - *1* *2* *3* [golang语言 map全方位介绍 【图文+代码】](https://blog.csdn.net/qq_45615577/article/details/122325035)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SoaringW

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值