Map是一种数据结构,是一个集合,用于存储一系列无序的键值对。它基于键存储的,键就像一个索引一样,这也是Map强大的地方,可以快速快速检索数据,键指向与该键关联的值。

内部实现

Map是基于 散列表 来实现,就是我们常说的 Hash 表,所以我们每次迭代Map的时候,打印的Key和Value是无序的,每次迭代的都不一样,即使按照一定的顺序存在也不行。

这种方式的好处在于,存储的数据越多,索引分布越均匀,所以我们访问键值对的速度也就越快,当然存储的细节还有很多,大家可以参考Hash相关的知识,这里我们只要记住Map存储的是无序的键值对集合。

声明和初始化

make函数

dict := make(map[string]int)

示例中创建了一个键类型为string的,值类型为int的空map。

dict["张三"] = 43

存储了一个Key为张三的,Value为43的键值对数据。

Map字面量

此外还有一种使用map字面量的方式创建和初始化map,对于上面的例子,我们可以同等实现。

dict := map[string]int{"张三":43}

使用一个大括号进行初始化,键值对通过:分开,如果要同时初始化多个键值对,使用逗号分割。

创建nil map

[danger]nil的Map是未初始化的,可以只声明一个变量,不分配内存

var dict map[string]int

这个 map是不能操作存储键值对的,必须要初始化后才可以,比如使用make函数, 为其开启一块可以存储数据的内存,也就是初始化。

var dict map[string]int
dict = make(map[string]int)
dict["张三"] = 43
fmt.Println(dict)

Map的键可以是任何值,键的类型可以是内置的类型,也可以是结构类型,但是不管怎么样,这个键可以使用==运算符进行比较,所以像切片、函数以及含有切片的结构类型就不能用于Map的键了,因为他们具有引用的语义,不可比较。

使用Map

Map的使用很简单,和数组切片差不多,数组切片是使用索引,Map是通过键。

赋值或更新

dict := make(map[string]int)
dict["张三"] = 43

判断键是否存在

age := dict["张三"]

在Go Map中,如果我们获取一个不存在的键的值,也是可以的,返回的是值类型的零值,这样就会导致我们不知道是真的存在一个为零值的键值对呢,还是说这个键值对就不存在。对此,Map为我们提供了检测一个键值对是否存在的方法。

age, exists := dict["李四"]

和获取键的值没有太大区别,只是多了一个返回值。

  • 第一个返回值是键的值;
  • 第二个返回值标记这个键是否存在,这是一个boolean类型的变量

删除

删除一个Map中的键值对,可以使用Go内置的delete函数。

delete(dict,"张三")

delete函数接受两个参数,第一个是要操作的Map,第二个是要删除的Map的键。

delete函数删除不存在的键也是可以的,只是没有任何作用。

遍历和排序Map

使用for range风格的循环,和遍历切片一样。

dict := map[string]int{"张三": 43}
for key, value := range dict {
fmt.Println(key, value)
}

这里的 range 返回两个值

第一个是Map的键

第二个是Map的键对应的值。

这里再次强调,这种遍历是无序的,也就是键值对不会按既定的数据出现,如果想安顺序遍历,可以先对Map中的键排序,然后遍历排序好的键,把对应的值取出来,下面看个例子就明白了。

package main

import (
"sort"
"fmt"
) func main() {
dict := map[string]int{"王五": 60, "张三": 43}
// 先对 names 的 slice 进行排序
var names []string
for name := range dict {
names = append(names, name)
}
// second method,当range 返回的第二个参数不需要使用时,可以舍弃,还是推荐第一种写法
/*
for name, _ := range dict {
names = append(names, name)
}
*/
sort.Strings(names)
// 按排序遍历
for _, key := range names {
fmt.Println(key, dict[key])
}
}

在函数间传递Map

map 是引用传递

func main() {
dict := map[string]int{"王五": 60, "张三": 43}
modify(dict)
fmt.Println(dict["张三"])
} func modify(dict map[string]int) {
dict["张三"] = 10
} // out
10

上面这个例子输出的结果是10,也就是说已经被函数给修改了,可以证明传递的并不是一个Map的副本。这个特性和切片是类似的,这样性能就会更高,因为复制整个Map的代价太大了。

和其他语言的差异

访问的 key 不存在时,仍会返回零值,不能通过 nil 来判断元素是否存在。

工厂函数

顾名思义,就好比一个工厂一样,可以批量制造某种类型的东西。其实说白了就是封装了个方法减少重复工作。

示例,通过map实现的计算平方,立方

mapx := map[int]func(n int) int{}
mapx[1] = func(n int) int { return n }
mapx[2] = func(n int) int { return n * n }
mapx[3] = func(n int) int { return n * n * n } fmt.Println(mapx[1](2))
fmt.Println(mapx[2](2))
fmt.Println(mapx[3](2))

示例,go 实现 set 集合

// new empty set
set := make(map[string]bool) // add
set["name"] = true
set["age"] = true
set["gender"] = true // loop
for k := range set {
fmt.Println(k)
} // delete
delete(set, "name") // exist
_, exist := set["age"]
if exist == true {
fmt.Println("Exist")
} else {
fmt.Println("Not Exist")
} // len
fmt.Println(len(set))

go set 参考

golang 基础 map及工厂函数的更多相关文章

  1. golang基础--map字典

    map 类似python语言中的dict(字典类型),以key-value形式存储数据 Key必须是支持==或!=比较运算的类型,不可以是函数,map或slice map查找比线性搜素快很多,但比使用 ...

  2. Golang基础之函数

    golang基础之函数 1.为什么需要函数? 有些相同的代码可能出现多次,如果不进行封装,那么多次写入到程序中,会造成程序冗余,并且可读性降低 2.什么是函数 为完成某些特定功能的程序指令集合称为函数 ...

  3. GoLang基础数据类型--->字典(map)详解

    GoLang基础数据类型--->字典(map)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   可能大家刚刚接触Golang的小伙伴都会跟我一样,这个map是干嘛的,是 ...

  4. jQuery基础的工厂函数以及定时器的经典案例

    1. jQuery的基本信息:  1.1 定义: jQuery是JavaScript的程序库之一,它是JavaScript对象和实用函数的封装, 1.2 作用: 许多使用JavaScript能实现的交 ...

  5. jQuery基础,定时器,工厂函数

    这个星期刚刚学的JQuery,下面我来说说我学的这几个例子 jQuery是JavaScript的一个程序库. Jquery的工厂函数$(): 在Jquery中 $符号等价于jquery,作用是将DOM ...

  6. Golang基础教程——map使用篇

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是golang专题的第7篇文章,我们来聊聊golang当中map的用法. map这个数据结构我们经常使用,存储的是key-value的键 ...

  7. python基础:内置函数zip,map,filter

    一.zip zip,就是把俩list,合并到一起,如果想同时循环2个list的时候,可以用zip,会帮你轮流循环两个list 比如: l1=[1,2,3,4,5] l2=['a','b','c','d ...

  8. Golang 基础之基础语法梳理 (三)

    大家好,今天将梳理出的 Go语言基础语法内容,分享给大家. 请多多指教,谢谢. 本次<Go语言基础语法内容>共分为三个章节,本文为第三章节 Golang 基础之基础语法梳理 (一) Gol ...

  9. Golang 基础之基础语法梳理 (一)

    大家好,今天将梳理出的 Go语言基础语法内容,分享给大家. 请多多指教,谢谢. 本次<Go语言基础语法内容>共分为三个章节,本文为第一章节 Golang 基础之基础语法梳理 (一) Gol ...

随机推荐

  1. 区间dp暂时的理解

    因为刚刚看了区间dp,所以写一下对区间dp的理解. 例题: 石子归并 51Nod - 1021 看了一篇博客,觉得他说得比较容易理解,所以再次重复一遍: 假如你是上帝,已经知道了1~n堆石子的最优解, ...

  2. 前端学习(3)-CSS

    一 CSS CSS是Cascading Style Sheets的缩写,层叠样式表,用来控制网页数据的显示,可以使网页的显示与数据内容分离. 二 引入方式 (1)行内式:在标记的style属性中设置C ...

  3. iOS 启动时间优化

    在 WWDC 2016 上首次提到了关于 App 应用启动速度优化的话题:Session 406 Optimizing App Startup Time. 一.冷启动与热启动 热启动是,APP会恢复之 ...

  4. LeetCode(一) jump game

    一. 1. #include<iostream> #include<cmath> using namespace std; bool CanJump(int n[],int n ...

  5. Java 异常处理与输入输出

    一.异常 1.1 package exception; import java.util.Scanner; public class ArrayIndex { public static void m ...

  6. Bootstrap 的基本实现

    bootstrap:   UI插件  YUI,  ElementUI Bootstrap 是最受欢迎的 HTML.CSS 和 JS 框架,用于开发响应式布局.移动设备优先的 WEB 项目. 响应式布局 ...

  7. twoway 系列命令绘制地图

    twoway 系列命令绘制地图 ❝ 在谈到用stata绘制地图时,很多人首先想到的是spmap命令.其实,最常见的twoway系列命令就可以完成我们的大多数绘图需求. 对于spmap命令的使用,在线资 ...

  8. VirtualBox 安装 Arch Linux 并配置桌面环境

    最近无聊,就找来 Arch Linux 来玩一玩,去 archlinux wiki上看了一下教程.以下是操作过程. 1. 下载镜像,下载地址; 2. 启动 Archlinux 并选择 Boot Arc ...

  9. SHTC3温湿度传感器的使用

    1.SHTC3简单说明 SHTC3是一个检测温度.湿度的传感器,可以检测-40℃~125℃的温度范围和0%~100%的湿度范围. SHTC3的工作电压范围为:1.62V~3.6V. SHTC3使用的通 ...

  10. DALI 48V驱动

    DALI-CC-30W-48V技术手册 产品名称:DALI-CC-30W-48V 支持协议:IEC 62386-101:2018,IEC 62386-102:2018,IEC 62386-207:20 ...