iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > GO >Go字典使用详解
  • 506
分享到

Go字典使用详解

Go字典Golang字典 2022-11-21 22:11:35 506人浏览 安东尼
摘要

目录存储/查找原理限制字典声明字典赋值特殊类型修改值字典遍历总结字典特性和许多编程语言一样,在 Go 中,字典是一组键-值对( Go 中称键-元素对)的集合。 存储/查找原理 当我们

和许多编程语言一样,在 Go 中,字典是一组键-值对( Go 中称键-元素对)的集合

存储/查找原理

当我们要存储或者查找某个键-元素对的时候,哈希表会先使用哈希函数将键值转换为哈希值,哈希值一般是一个无符号的整数。

一个哈希表内会存有一定数量的哈希桶,在字典的结构里面,有一个属性 B ,这个属性代表当前字典里面桶的个数 (2^B) 。

	// A header for a Go map.
	type hmap struct {
	   // Note: the fORMat of the hmap is also encoded in cmd/compile/internal/GC/reflect.go.
	   // Make sure this stays in sync with the compiler's definition.
	   count     int // # live cells == size of map.  Must be first (used by len() builtin)
	   flags     uint8
	   B         uint8  // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
	   noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
	   hash0     uint32 // hash seed
	   buckets    unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
	   oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
	   nevacuate  uintptr        // progress counter for evacuation (buckets less than this have been evacuated)
	   extra *mapextra // optional fields
	}

比如当 B 为 5 的时候,通过获取哈希值的低 5 位就能判断出当前键-元素对应该存放在哪一个桶里面。例如我们通过哈希函数,获取到了一个键-元素对中键值的哈希值为

1001011100001111011011001000111100101010001001011001010101011011

其中,低 5 位代表其所属的桶的位置,11011 换算为十进制为 26 ,即该键-元素对存在第 26 个桶内。哈希桶内存储的是“键的哈希值-内部结构”对的集合,即是按照 键1 键2 … 键8 元素1 元素2 … 元素8 溢出指针 的方式存储,是一块连续的内存,且键和元素时捆绑存储的。我们找到哈希桶之后,再对比键值,就可以定位我们所以需要的键的位置,又因为键 - 元素对是捆绑存储的,所以找到了键就等于是找到对应的元素值。

存储时也是同样的道理,但是要注意的是,每一个存储桶最多只能存储 8 个键-元素对,当超出 8 个的时候,就会生成一个溢出桶,并且当前哈希桶的溢出指针(上述连续内存的最后一块)会指向新生成的溢出桶。

限制

其实从上面就可以看出,字典类型其实是一个哈希表的一个特定实现,其中键和元素的最大区别在于键必须是可以哈希的,而元素却可以是任意类型的,因此字典中的键类型是受限的。

字典声明

// 声明字典 是个 nil 未初始化,直接存值会报错
var s0 map[string] int
// 声明字典并初始化
s1 := map[string]int{}    
// 使用 make 声明
s2 := make(map[string] int)
fmt.Println(s0, s1, s2, s3)

-------结果-------------------------
map[] map[] map[]

要注意:声明字典的时候 key 的类型不能是函数、字典、切片。因为根据上面查找字典键-元素对的过程可以知道,最后是要通过比较桶内键和要查询的键是不是一样来确定键-元素对的位置的,但是这三种类型不支持判等操作,所以键的类型不支持这三种,编译器会直接报错。

但是有一个比较特殊的类型:接口 interface{},interface{} 是支持判等操作的,所以编译器不会报错。但是又因为 interface{} 这个空接口相当于是个万能类型,可以接受任何类型的值,所以会出现以下情况的代码:

var s4 = map[interface{}]int{
	"1":      1,
	[]int{2}: 2,
	3:        3,
}
fmt.Println(s4)

------结果--------------
panic: runtime error: hash of unhashable type []int

当我们运行时,就会出现 panic 恐慌。程序运行出现这样的报错我们还能及时调整,但在程序运行时,我们添加了这样的键值对进去导致系统异常,再修改就为时已晚了,所以我们最好不要使用 interface{} 作为键的类型,而且我们要优先考虑计算哈希值比较快的类型作为字典的键类型 。

字典赋值

//初始化
s0 := map[string]int{}
fmt.Println(s0)
//添加key-value
s0["one"] = 1
s0["two"] = 2
fmt.Println(s0)
//修改指定key的值
s0["one"] = 11
s0["two"] = 22
fmt.Println(s0)
//删除指定key的元素
delete(s0, "one")
fmt.Println(s0)
//获取key-value对个数
fmt.Println(len(s0))

------结果-------------------
map[]
map[one:1 two:2]
map[one:11 two:22]
map[two:22]
1

特殊类型修改值

如果值的类型是数组或者结构体,那么不能直接修改 value 成员

s0 := map[string]struct {
	x int
}{}
s0["one"] = struct{ x int }{1}
s0["two"] = struct{ x int }{2}
s0["one"].x = 1 //这里编译器会直接报错

方法一:先获取全部value,修改之后重新赋值

s0 := map[string]struct {
	x int
}{}
s0["one"] = struct{ x int }{1}
s0["two"] = struct{ x int }{2}
s0["one"].x = 1 //这里编译器会直接报错
// 正确做法一
s1 := s0["one"]
s1.x = 111
s0["one"] = s1 
fmt.Println(s0)

-----结果------------------
map[one:{111} two:{2}]

方法二:使用指针类型

* 开头表示是指针类型

& 是取址符号,即获取对应程序实体对象的地址

// 正确做法二 
// value 的类型是指针类型,指针指向结构体
s0 := map[string]*struct {
	x int
}{}
//创建一个结构体并把指针添加到字典中
s0["one"] = &struct{ x int }{1}
fmt.Println(*s0["one"])
s0["one"].x = 111
fmt.Println(*s0["one"])

-----结果------------------
{1}
{111}

字典遍历

s0 := map[string]int{}
s0["one"] = 1
s0["two"] = 2
//接收 key 和 value
for k, vla := range s0 {
	fmt.Printf("%s:%d\n", k, vla)
}
fmt.Println("-----分割线---------------")
//只接收key
for k := range s0 {
	fmt.Printf("%s:%d\n", k, s0[k])
}

-----结果----------------
one:1
two:2
-----分割线---------------
one:1
two:2

总结字典特性

  • 字典的键类型是有限制的,必须支持哈希和判等
  • 字典是无序的,每次遍历的顺序都可能不一样
  • 如果值类型是结构体或者数组,那么不能直接对值的成员进行操作
  • 不能对 nil 字典进行赋值操作,但是可以读,读出来是一个空字典 map[]
  • 字典是线程安全的,多个线程对同一个字典进行操作会导致报错
  • 可以在迭代过程中删除或者添加键-元素对

到此这篇关于Go字典使用详解的文章就介绍到这了,更多相关Go字典内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

您可能感兴趣的文档:

--结束END--

本文标题: Go字典使用详解

本文链接: https://www.lsjlt.com/news/173328.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Go字典使用详解
    目录存储/查找原理限制字典声明字典赋值特殊类型修改值字典遍历总结字典特性和许多编程语言一样,在 Go 中,字典是一组键-值对( Go 中称键-元素对)的集合。 存储/查找原理 当我们...
    99+
    2022-11-21
    Go字典 Golang字典
  • Python字典使用技巧详解
    目录1. 引言2. 使用union操作合并字典3. 使用解包操作合并字典4. 使用字典生成式5. 字典中key-value互换6. 列表转为字典7. 字典按照value来排...
    99+
    2022-11-16
    Python字典用法 Python字典
  • Python 字典 get()函数使用详解,字典获取值
    「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:小白零基础《Python入门到精通》 get函数使用...
    99+
    2023-10-20
    python 网络安全 人工智能 机器学习
  • C#泛型字典Dictionary的使用详解
    本文主要介绍了C# 泛型字典 Dictionary的使用详解,分享给大家,具体如下: 泛型最常见的用途是泛型集合,命名空间System.Collections.Generic 中包含...
    99+
    2024-04-02
  • python字典详解
    字典是Python中唯一的內建的映射类型,可以存储任意对象的容器,比如:字符串,列表,元组,自定义对象等;字典由键(key)与值(value)组成,基本语法如下: {key:value, ... ...}字典中每个Key是唯一的,key必...
    99+
    2023-01-31
    字典 详解 python
  • Python 字典详解
    目录什么是字典?创建字典1. 直接赋值2. 使用 dict()函数创建空字典3. 获取字典元素4. 唯一的键,如果字典中有俩个或多个相同的键,默认取最后一个小结:字典的增字典的改&n...
    99+
    2024-04-02
  • Python 字典的使用详解及实例代码
    目录字典长什么样字典内能放什么访问字典内容修改字典内容删除字典数据字典内置函数字典是Python实现散列表数据结构的形式,表现映射的关系,一对一。 字典长什么样 {}这是一个空字典,...
    99+
    2024-04-02
  • Python 中字典dict详解
    一、字典(dict)概念 字典是另一种可变容器模型,且可存储任意类型对象如字符串、数字、元组等其他容器模型,因为字典是无序的所以不支持索引和切片。 二、字典(dict)的定义 一般格式: 字典的每个键...
    99+
    2023-09-01
    python 开发语言
  • 详解Python合并字典
    目录实例 1 : 使用 update() 方法,第二个参数合并第一个参数实例 2 : 使用 **,函数将参数以字典的形式导入总结给定一个字典,然后计算它们所有数字值的和。 实例 1 ...
    99+
    2024-04-02
  • Oracle数据字典详解
    目录1. 什么是oracle数据字典2. 数据字典的内容3. 数据字典应用示例1. 什么是Oracle数据字典 数据字典(Data Dictionary)是Oracle元数据(Metadata)的存储地点,汇集了数据库对...
    99+
    2023-04-19
    Oracle数据字典介绍 Oracle数据字典 Oracle数据
  • Python学习之字典和集合的使用详解
    目录字典简介字典的基本方法字典元素添加获取字典键对应的值字典元素的修改字典元素的删除字典的遍历集合学习集合添加元素集合删除元素统计集合个数,判断元素是否存在,清空集合集合运算字典简介...
    99+
    2024-04-02
  • Python字典的详细讲解
    本篇内容介绍了“Python字典的详细讲解”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、字典概述1. 字典的格式Python字典是一种可...
    99+
    2023-06-16
  • 详解Python字典的运算
    目录问题描述解决方案讨论总结问题描述 怎样在数据字典中执行一些计算操作(比如求最值、排序等)? 解决方案 有如下字典: stocks = { 'ACME': 45.23,...
    99+
    2024-04-02
  • JavaScript字典与集合详解
    目录字典什么是字典JavaScript中的字典字典的应用集合什么是集合JS中的集合集合中的操作交集、并集、差集的封装字典 什么是字典 说到字典,第一时间想到的应该就是新华字典,实际上...
    99+
    2024-04-02
  • Python中字典及遍历常用函数的使用详解
    目录字典中元素的个数计算字典中的键名加粗样式字典中的键值字典的键名以及对应的键值字典的遍历方法一方法二字典中元素的个数计算 len(字典名) 举例: person={"姓名":"张三...
    99+
    2024-04-02
  • python列表,元祖,字典详解
    列表:    基础数据类型,可含有大量数据,可存储各种数据类型    1,索引切片    与字符串一样    2,增删改查,以及其他操作        增        append 追加          insert  列表.inser...
    99+
    2023-01-31
    元祖 字典 详解
  • python生成密码字典详解
    代码和代码运行的结果: 代码: import itertools as its words="rot123" a=its.product(words,repeat=4) name...
    99+
    2024-04-02
  • 详解Python字典查找性能
    目录timeit.repeat字典获取性能数据准备复杂获取总结timeit.repeat timeit.repeat默认会执行3轮,每轮执行1000000次。返回每轮的总执行时间列表...
    99+
    2024-04-02
  • Python 之 字典使用
    字典的增删改查使用 1、增加 info = { "person1":"大s", "person2":"小s", "person3":"小3", "person4":"小4" } info["person5"]...
    99+
    2023-01-31
    字典 Python
  • Python字典使用(八)
    字典描述:字典是另一种可变容器模型,且可以存储任意类型对象。字典的每个键值(key=>value)对用冒号分隔,每对之间用逗号分割,整个字典包括花括号在内,如下所示:d={key1:value1,key2:value2}键必须是唯一的...
    99+
    2023-01-31
    字典 Python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作