【Go语言学习】——Map

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"])
    
    }
    

你可能感兴趣的:(golang,学习,开发语言)