文档章节

【golang学习笔记】map

z
 zozol
发布于 2018/02/28 22:36
字数 958
阅读 15
收藏 0

map学习笔记

golang中的map数据结构类似于java中的HashMap,能够自动扩容,非并发安全,并且key是无序的。

关于为什么在golang中map是内建的数据结构,可以见golang官方faq:https://golang.org/doc/faq#builtin_maps(国内可以使用这个网址访问:https://golang.google.cn/doc/faq#builtin_maps)

map的基本用法

// map的声明方式
var map1 map[keytype]valuetype

// 由于map是引用类型,因此必须显示初始化,否则默认值是nil
var si map[string]int
fmt.Println(si == nil) // true
si["monday"] = 1 //panic: assignment to entry in nil map

//map的初始化方式主要有两种:make方式和literal方式

// 1.采用make分配内存
//采用默认大小
var map1 map[string]int = make(map[string]int)
// 显示指定大小,如果你要往map放入大量数据,最好在新建map的时候显示指定map大小,
// 否则会导致map频繁扩容,影响性能
var map1 map[string]int = make(map[string]int, 100)

map1["age"] = 1

// 2.literal方式初始化
map1 := map[string]int{
    "Monday": 1,
    "Tuesday":2
}

map的常用操作:get、set、delete
// 1.set:给map赋值
map1["Wednesday"] = 3

// 2.get:根据指定key从map中获取value
//根据key获取map中的value,这里如果指定key在map中不存在的话
//会返回valuetype的"零值"(golang中的"零值"定义TODO)
fmt.Println(map1["Wednesday"]) // print 3
fmt.Println(map1["hello"]) // print 0 (0 是int类型的零值)

//为了避免这种情况可以使用下面的赋值语句进行测试
v, ok := map1["Wednesday"]

if v, ok := map1["Wednesday"]; ok {
 //process
}

// 3.delete:根据指定key从map中删除值
delete(map1, "Monday")

// 4.通过len()获取map当前的大小,不能对map使用cap()
fmt.Println(len(map1))


  • map的key说明:官方文档中阐述只要是任何定义了equal操作的类型都可以当做map的key,比如integers, floating point and complex numbers, strings, pointers, interfaces,channel、structs 和 arrays。而func、slice、map不能作为key,因为它们没有定义equal操作。对于struct、interface和array来说,如果它们要作为key,必须它们包含的元素都可以作为key才行,如下测试代码:
  type Person struct {
	name string
	age int
}

type Person2 struct {
	name string
	age int
	friends []string
}

// struct作为map的key测试
  var test map[Person]int = make(map[Person]int) // struct类型作为key
	test[Person{"fuqiu", 20}] = 100
	fmt.Println(test[Person{"fuqiu", 20}]) // 输出100

   // interface作为map的key测试
	keyArray := [2]interface{}{1, "2"} 
	var keyArrayMap map[[2]interface{}]int = make(map[[2]interface{}]int)
	keyArrayMap[keyArray] = 10000
	fmt.Println(keyArrayMap[keyArray]) // 输出10000

// interface{}类型作为key,但是其中包含func(){}元素,此时运行时报错
	keyArray2 := [2]interface{}{1, func(){}} // 报错信息:panic: runtime error: hash of unhashable type func()
	var keyArrayMap2 map[[2]interface{}]int = make(map[[2]interface{}]int)
	keyArrayMap2[keyArray2] = 20000
	fmt.Println(keyArrayMap2[keyArray2])
	
	//使用包含了slice的struct作为key,因为slice不能作为map的key,因此运行时报错
	var test2 map[Person2]int = make(map[Person2]int)
	test2[Person2{"fuqiu", 20, []string{"1", "2"}}] = 1000
	fmt.Println(test2[Person2{"fuqiu", 20, []string{"1", "2"}}]) // 报错信息:invalid map key type Person2
  • valuetype说明:可以是任意类型的;通过使用interface{}类型,我们可以存储任意值
  • 在声明的时候不需要知道 map 的长度,map 是可以动态增长的。
  • 未初始化的 map 的值是 nil

map一些需要注意的点

  • map 是引用类型
  • map的key是无序的(TODO:如何实现有序)
  • 不要使用 new,永远用 make 来构造 map,如果你错误的使用 new() 分配了一个引用对象,你会获得一个空引用的指针,相当于声明了一个未初始化的变量并且取了它的地址
mapCreated := new(map[string]float32)
// 以下操作编译器会报错:invalid operation: mapCreated["key1"] (index of type *map[string]float32).
mapCreated["key1"] = 4.5

map的一些使用技巧

  • map[string]bool 来实现set的效果
  • map[string]func(){}

map的实现原理

TODO

参考资料

© 著作权归作者所有

z
粉丝 1
博文 5
码字总数 1020
作品 0
杭州
高级程序员
私信 提问
Golang学习笔记目录

Golang 介绍 Go语言是谷歌2009发布的第二款开源编程语言。 Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全、支持并行进程。...

ChainZhang
2017/12/26
0
0
go语言文件汇总

归并排序及go语言实现 堆排序算法及go语言实现 Go语言基础学习(一)变量 【Leetcode】:Counting Bits问题 in Go语言 基于go语言的心跳响应 【Leetcode】:Single Number III问题 in Go语言 ...

d_watson
2016/04/15
137
2
golang入门学习笔记(一)

作者: 一字马胡 转载标志 【2017-11-21】 更新日志 日期 更新内容 备注 2017-11-21 新建文章 go语言入门笔记(一) 准备环境 在Mac下,可以使用下面的命令安装golang: 完成安装之后,可以命...

一字马胡
2017/11/21
0
0
Go圣经-学习笔记之方法值和表达式

上一篇 Go圣经-学习笔记之封装还是组合 下一篇 Go圣经-学习笔记之接口 方法值和方法表达式 了解过前面的函数值用法,应该就会使用方法值,在方法值中,接收者对象成为了引用环境中的参数变量...

cdh0805010
2017/10/27
83
0
Go圣经-学习笔记之复合类型(三)

上一篇 Go圣经-学习笔记之复合类型(二) 下一篇 Go圣经-学习笔记之函数和错误处理 json数据的序列化和反序列化 json的全称是Javascript object notation, 中文全称:js对象表示法。在序列化和...

cdh0805010
2017/10/24
161
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Security 实战干货:实现自定义退出登录

1. 前言 上一篇对 Spring Security 所有内置的 Filter 进行了介绍。今天我们来实战如何安全退出应用程序。 2. 我们使用 Spring Security 登录后都做了什么 这个问题我们必须搞清楚!一般登录...

码农小胖哥
5分钟前
2
0
JVM核心知识-类加载机制

JVM中类的生命周期包括7个阶段,加载、准备、验证、解析、初始化、使用、卸载。其中准备、验证、解析被归为连接阶段。 加载 jvm在这个阶段完成的工作 通过类名获取类的二进制字节流 将这个字...

moon888
5分钟前
1
0
.net工作流引擎ccflow流程结束相关功能的介绍

关键字: 工作流程管理系统 工作流引擎 asp.net工作流引擎 java工作流引擎. 表单引擎 工作流功能说明 工作流设计 工作流快速开发平台 业务流程管理 bpm工作流系统 java工作流主流框架 自定义...

孟娟
19分钟前
3
0
APP 值入轻量级钱包以太坊网络钱包

APP 值入轻量级钱包以太坊网络钱包

xiaodong16
23分钟前
3
0
云原生下数据治理的微服务架构

摘要: 现代软件发展历程中,微服务概念早在2014年由两位美国学者提出,2015年云原生也在linux基金会的推动下茁壮成长。短短几年,越来越多的公司投入研究,越来越多的技术框架孕育而生。本文...

恒宝乐园
30分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部