• Go Map


    #### Go map 
    ***如果生命是一道墙,那么声声必有回响***
    上一节我们学习了数组与切片,学习的还是基础部分, 高级部分有二维数组,多维数组...;
    在这里先不写高级部分,高级部分与初级部分并没有太大区别,一个是多维切片,在每一维使用前都需要make,第二个是遍历时需要多层循环;
    ##### map
    在 Go 中map 是key:value 数据结构,类似python 中的字典;
    基本语法:
    var 变量名 map[keyType]valueType
    其中key 可以是如下类型:
    bool, 数字,string, 指针, channel,同样还可以是包含前几个类型的接口,结构体,数组;
    不过一般开发使用中key 通常为int,string;
    key 需要满足可以使用== 判断,所以slice,map,函数这三个类型不可以作为map 的key ;
    value 的数据类型同key 一样, 通常为数字,string, map,struct;
    案例:
    var a map[string]string 
    var b map[int]string 
    var c map[string]map[int]string 
    var d map[string]int
    

      


    map 是引用类型和slice 同样,声明或定义是不会分配内存,初始化都需要make 才能使用;
    package main
    
    import "fmt"
    
    func main(){
       var a map[string]string
       a = make(map[string]string)
       a["01"] = "01"
       a["02"] = "02"
       a["03"] = "03"
       a["01"] = "04"
       fmt.Println(a)
    }
    

      


    1. map 在使用前需要make ;
    2. map 的key 不能重复,如果重复则key 的值为最后一次赋的值 ;
    3. map 是无序的,所以如果需要对map 排序,则需要对key 进行排序 ;
    ---
    ##### map 的声明和初始化方式
    package main
    
    import "fmt"
    
    func main(){
       // 1. 先声明,再make ,最后使用
       var a map[string]string
       a = make(map[string]string)
       a["01"] = "01"
       fmt.Println(a)
       // 2. 直接使用类型推导
       b := make(map[string]string)
       b["01"] = "01"
       fmt.Println(b)
       // 3. 字面量方式
       var c = map[string]string{
          "01":"01",
       }
       fmt.Println(c)
    }
    

      


    ##### map 的增删改查
    map 的增加和更改
    map[key] = value // 如果map 内不存在key 则属于添加操作,否则属于更改操作;
    package main
    
    import "fmt"
    
    func main(){
       // 1. 先声明,再make ,最后使用
       var a map[string]string
       a = make(map[string]string)
       // 增加操作
       a["01"] = "01"
       a["02"] = "02"
       // 更改操作
       a["01"] = "10"
       fmt.Println(a) // map[01:10 02:02]
    }
    

      


    map 删除
    delete(map,key) ,delete 是内置函数,如果key 存在则会删除这对key:value,如果key 不存在,则不会操作,也不会报错;
    package main
    
    import "fmt"
    
    func main(){
       // 1. 先声明,再make ,最后使用
       var a map[string]string
       a = make(map[string]string)
       // 增加操作
       a["01"] = "01"
       a["02"] = "02"
       // 更改操作
       a["01"] = "10"
       fmt.Println(a) // map[01:10 02:02]
       // 删除已经存在的key
       delete(a,"02")
       // 删除不存在的key 
       delete(a,"10")
    }
    

      


    ---
    注意: 在Go 中没有专门的函数可以一次性删除map 中所以的key, 也就是说没有办法一次性清空map,
    如果需要删除所有的key, 则需要遍历map , 一个一个删除; 另一个办法则是让gc 回收: map = make(map[keyType][valueType]);

    map 查找
    val,res = map[key]
    如果map 中存在key 则返回value,同时返回res=true,否则不会返回value,res=false;
    package main
    
    import "fmt"
    
    func main(){
       // 1. 先声明,再make ,最后使用
       var a map[string]string
       a = make(map[string]string)
       // 增加操作
       a["01"] = "01"
       a["02"] = "02"
       var value string
       var res bool
       value,res = a["01"]
       if res {
          // 如果有这个key
          fmt.Println("key:01 value:",value)
       } else {
          // 如果没有这个key
          fmt.Println("no value",value)
       }
       value,res = a["10"]
       if res {
          // 如果有这个key
          fmt.Println("key:10 value:",value)
       } else {
          // 如果没有这个key
          fmt.Println("no value",value)
       }
    }
    

      


    ##### map 的遍历
    map 的遍历方式可以使用for-range 方式
    package main
    
    import "fmt"
    
    func main() {
       // 1. 普通的map
       var a map[string]string
       a = make(map[string]string)
       // 增加操作
       a["01"] = "01"
       a["02"] = "02"
       for key,value := range a {
          fmt.Println(key+"=",value)
       }
       // map 的value 还是一个map
       var b map[string]map[string]string
       b = make(map[string]map[string]string)
       b["01"] = map[string]string{"001":"0001"} // 第二层这里使用的是字面量方式
       // 也可以使用这样的方式
       c := make(map[string]string)
       c["002"] = "0002"
       b["02"] = c
       fmt.Println(b)
       // 复杂map 的遍历
       for key,value := range b {
          for key2,value2 := range value {
             fmt.Printf("first key=%s,first value=%v | second key=%s,second value=%s
    ",key,value,key2,value2)
          }
       }
    }
    

      


    ##### map 的长度使用len 函数
    ##### map 类型的切片
    如果切片的数据类型是map , 那么map 的个数就可以动态变化了,这个在json 中比较常用,json 序列化和反序列化后面会学习到;
    package main
    
    import "fmt"
    
    func main() {
       // 声明切片的类型为map
       var arr []map[string]string
       // 声明一个map 类型
       var a map[string]string
       // 初始化map
       a = make(map[string]string)
       // map 赋值
       a["01"] = "01"
       // 初始化切片
       arr = make([]map[string]string,0) // append 函数底层会检查是否make ,所以这一行可以省略;
       arr = append(arr,a)
       // 再添加一个map
       var b map[string]string
       b = make(map[string]string)
       b["001"] = "001"
       arr = append(arr,b)
       fmt.Println(arr)
    }
    

      


    ##### map 排序
    在上面我们知道了,map 本身是无序的,所以排序需要先对key 排序,然后按排序后的key 输出map即可;
    package main
    
    import (
       "fmt"
       "sort"
    )
    
    func main() {
       var a map[string]string
       a = make(map[string]string)
       a["01"] = "01"
       a["first"] = "first"
       a["second"] = "second"
       a["third"] = "third"
       a["fourth"] = "fourth"
       // 输出是无序的,多运行几次即可看到
       for k,v := range a {
          fmt.Println(k,v)
       }
       // 对map 排序,需要先对key 排序
       var keySlice []string
       for key,_ := range a {
          keySlice = append(keySlice,key)
       }
       // 排序
       // 排序前
       fmt.Println(keySlice)
       sort.Strings(keySlice)
       // 排序后
       fmt.Println(keySlice)
       // 按排序后的key 输出map
       for _,key := range keySlice {
          fmt.Println(key,a[key])
       }
    }
    

      


    map 的使用注意事项
    1. map 是引用类型,遵守引用类型传递机制,在函数内部修改后,会改变原来的值 ;
    2. map 会自动扩容,可以动态增长;
    package main
    
    import "fmt"
    
    func test01(a map[string]string){
       // 新增加一个key:value
       a["02"]    = "02"
    }
    func main() {
       var a map[string]string
       a = make(map[string]string)
       a["01"] = "01"
       a["first"] = "first"
       // 传入函数前
       fmt.Println(a) //map[01:01 first:first]
       // 传入函数后
       // 可以看出map 是引用类型,遵守引用传递机制
       test01(a)
       fmt.Println(a) //map[01:01 first:first 02:02]
    }
    

      最新文章会在微信公众号,欢迎关注学习交流

  • 相关阅读:
    Jocke的IOT之路--raspberrypi更换国内镜像
    利用PostMan 模拟上传/下载文件
    Java中的Lambda表达式
    设计模式之Jdk动态代理
    设计模式之代理模式
    Java内存模型及Java关键字 volatile的作用和使用说明
    JVM GC-----4、finalize()方法
    JVM GC-----3、垃圾对象的标记思路(二)
    JVM GC-----2、垃圾对象的标记思路(一)
    JVM GC-----1、垃圾回收算法
  • 原文地址:https://www.cnblogs.com/Mail-maomao/p/11458906.html
Copyright © 2020-2023  润新知