golang学习笔记-map类型

旧梦发癫 · · 2351 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

在刚刚接触go语言的时候,就看到很多地方出现了map。就对这个map很困惑,那么这个map究竟是什么呢。让我们一起来看一看吧。

map (映射)是一个种数据结构,用于存储一些无序的键值对。映射使用了两个数据结构来存储数据。第一个数据结构是数组,内部存储的是用户选择桶的散列值。第二个数据结构是一个字节数组,用于存储键值对。映射是一个存储键值对的无序集合。

创建和初始化

go语言中可以使用make函数,也可以使用使用字面量的方法来创建映射(map)。如下所示

 //通过make函数 创建一个映射,键类型是string ,值是int
   list := make(map[string]int)
   list["test"]= 1
   fmt.Println(list["test"])
   
   //创建一个映射,键值都是string  使用字面量
   data := map[string]string{"top":"is top","bottom":"is bottom"}
   fmt.Println(data["top"])

创建映射更常用的方法应该是使用字面量,映射的初始长度会根据初始化时指定的键值对数量来确定,映射的键可以是任何值,这个值可以是内置类型,也可以是结构类型,只要这个值可以用==运算符比较。需要注意是:切片,函数以及包含切片的结构不能做为映射的键。

映射的使用

赋值
   //通过make函数 创建一个映射,键类型是string ,值是int
   list := make(map[string]int)
 //将test的值加入映射
   list["test"]= 1

可以通过什么一个未初始化的映射来创建一个nil映射,nil映射不能用于储存键值对

  var numbers map[int]int
   numbers[1]=1 //这里会产生一个错误
判断键是否存在于映射以及取值

判断某个键是否存在于映射中是一个经常使用的操作。从映射中取值时有两个方式。第一个是,同时获取值,以及一个表示键是否存在的标志

 data := map[string]string{"top":"is top","bottom":"is bottom"}
   val,exists := data["top"]
   //如果这个键存在
   if exists {
      fmt.Println(val)
   }  else {
      fmt.Println("top 不存在")
   }

第二个方式是,只获取键对应的值,通过这个值是否是零值来判断是否存在。但是如果这个键对应的刚好是零值,那么这个判断就会不准确

 data := map[string]string{"top":"is top","bottom":""}
   v := data["bottom"]
   if v!="" {
      fmt.Println(v)
   }else {
      fmt.Println("bottom 不存在")
   }
   v2 := data["left"]
   if v2!="" {
      fmt.Println(v2)
   }else {
      fmt.Println("left 不存在")
   }

以上代码会得到

bottom 不存在
left 不存在

但实际上映射中是存在键bottom

映射的迭代和数组、切片的迭代一样,使用range关键字
data := map[string]string{"top":"is top","bottom":"is bottom","left":"is left","right":"is right"}
   for k,v := range data{
      fmt.Printf("k:%s  v:%s\n",k,v)
   }

需要注意的是,因为映射是一个无序集合。所以每次迭代得到的键值对顺序是不一样的。

删除映射中的某一个项,使用内置函数delete
   data := map[string]string{"top":"is top","bottom":"is bottom","left":"is left","right":"is right"}
  delete(data,"top")
映射的传递(引用类型)

在函数间传递映射并不会制造出该映射的一个副本。实际上,当传递映射给一个函数,并对
这个映射做了修改时,所有对这个映射的引用都会察觉到这个修改。

func main() {
     m := map[int]int{
         0:0,
         1:1,
         2:2,
         3:3,
     }

    fmt.Println(m)
    changeMap(m)
    fmt.Println(m)
     delMap(m)
    fmt.Println(m)


}
func changeMap(m map[int]int)  {
        m[1]=111
}

func delMap(m map[int]int)  {
    delete(m,1)
}

上面示例将会输出

map[0:0 1:1 2:2 3:3]
map[0:0 1:111 2:2 3:3]
map[0:0 2:2 3:3]

可以看到在changeMap中改变了map的值或者delMap中删除了某一直键值对,main中的值也改变了。这个特性和切片类似,保证可以用很小的成本来复制映射。

1220188706-5d48273c534a2_articlex


有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:旧梦发癫

查看原文:golang学习笔记-map类型

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2351 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传