Map
Map在Go中提供映射关系的基于key-value的数据结构,,实际上内部使用的hash表实现的引用类型,必须初始化才能使用。判断map中的值时注意先判断错误,再执行操作。凡是返回有值和错误的都要先判断错误,因为有错误值为空,没有错误才有值。
package main
import (
"fmt"
"math/rand"
"sort"
"time"
)
//map的定义格式 :map[kyytype]type
//map为引用类型,直接声明后是nil,需要分配内存后才能使用
func main() {
//使用make为map类型分配内存,第二个参数指定具体大小,如果没有写则默认分配一个较小的内存
//而且map内存不够也会自动扩容
m1 := make(map[string]int, 8)
m1["卡卡"] = 100
m1["晨雨"] = 200
fmt.Println(m1)
fmt.Println(m1["卡卡"]) //输出要求的key对应的value
fmt.Println(m1["kk"]) //如果不存在这个key则输出对应value类型的零值,此处输出int类型的0
// map也支持声明时填充元素,这时会开辟比填充了的元素还要大些的内存,因此初始化时值为空也会开辟内存
userInfo := map[string]string{
"username": "沙河小王子",
"password": "123456",
}
// 开辟的内存比初始化加入元素需要的内存大,所以能继续添加
userInfo["卡卡"] = "zq"
fmt.Println(userInfo)
//判断map中某个值是否存在,使用value, ok := map[key]格式,其中ok为布尔值检验存在性
v, ok := m1["cy"]
if !ok {
fmt.Println("不存在")
} else {
fmt.Println(v)
}
//使用for range遍历map,无序
for k, v := range m1 {
fmt.Printf("Key=%s,value=%d\n", k, v)
}
//map中的for range只用一个变量接受时只接受key
for k := range m1 {
fmt.Println(k)
}
//map中的只要value就必须用匿名变量了
for _, v := range m1 {
fmt.Println(v)
}
//使用delete删除map中的某个值,delete格式为delete(map,key)
delete(m1, "卡卡")
delete(m1, "12313") //删除不存在的key的值不会有影响
fmt.Println(m1)
//按照指定顺序遍历map
rand.Seed(time.Now().UnixNano()) //初始化随机数种子
var scoreMap = make(map[string]int, 200)
for i := 0; i < 100; i++ {
key := fmt.Sprintf("stu%2d", i) //生成stu开头的字符串,02d表示长度为2,而且如果没有两位用0补充
value := rand.Intn(100) //生成0~99的随机整数
scoreMap[key] = value
}
// fmt.Println(scoreMap)
//取出map中的所有key存入切片keys
var keys = make([]string, 0, 200)
for key := range scoreMap {
keys = append(keys, key)
}
//对切片进行排序
sort.Strings(keys)
//按照排序后的key遍历map
for _, key := range keys {
fmt.Println(key, scoreMap[key])
}
//元素类型为map的切片
a := make([]map[int]string, 10)
a[0] = make(map[int]string, 1)
a[0][999] = "kaka"
fmt.Println(a)
//值为切片的map
b := make(map[string][]int, 10)
b["北京"] = []int{10, 20, 30}
fmt.Println(b)
}
-
Map与自增自减
如果map的值是int类型的,则直接可以使用++或者–表示对对应键的值进行自增(减),如果key还不存在,则会自动生产对应的key然后值为0,然后在这基础上进行自增自减
func main() { m := make(map[int]int) m[0]++ m[1]-- fmt.Printf("%v", m)//m[0]=1,m[1]=-1 }
-
Map的Key
slice,map,包含了slice的function和struct不能够作为Map的Key,而数字,string,bool,数组,channel,指针都可以作为key
这是因为map的key必须是可以比较的(可以使用==运算符的称为可比较),因为切片是引用类型,而且包含了len,cap多个维度不好衡量,所以切片不能比较,而由于map的value可以是slice所以也不能作为key。而包含了slice的函数和struct也不能比较。
-
Map练习
package main import ( "fmt" "strings" ) func main() { s := "how do you do I am fine thank you and you" res := strings.Split(s, " ") m := make(map[string]int, 10) for _, v := range res { x, ok := m[v] if ok { m[v] = x + 1 } else { m[v] = 1 } } fmt.Println(m) type Map map[string][]int m1 := make(Map) s1 := []int{1, 2} s1 = append(s1, 3) fmt.Printf("%+v\n", s1) m1["q1mi"] = s1 s1 = append(s1[:1], s1[2:]...) fmt.Printf("%+v\n", s1) //s的长度被修改了,而m["q1mi"]的长度没变,但两者还是指向同一个数组 fmt.Printf("%+v\n", m1["q1mi"]) }