专栏名称: 狗厂
目录
相关文章推荐
江苏教育发布  ·  考研复试有变!划重点→ ·  23 小时前  
江苏教育发布  ·  考研复试有变!划重点→ ·  23 小时前  
包头晚报  ·  考研复试有变! ·  昨天  
包头晚报  ·  考研复试有变! ·  昨天  
如东新媒体  ·  分数线已公布! ·  3 天前  
如东新媒体  ·  分数线已公布! ·  3 天前  
51好读  ›  专栏  ›  狗厂

Go语言map实践

狗厂  · 掘金  ·  · 2018-05-23 02:59

正文

计算机科学中最有用的数据结构是哈希表,许多哈希表的实现包含多种属性,但总的来说基本包含快速查找、添加和删除。Go语言的内建类型——映射(map)就通过哈希表实现。

声明和初始化

Go语言中的映射类型看起来像这样:

map [KeyType] ValueType

KeyType可以是任意可比较的类型 、ValueType可以是任意类型,甚至是一个其他的映射。如下m为映射类型的变量,Key是string类型的,Value是int类型:

var m map[string]int

映射是引用类型,类似于指针或切片(slice),所以上面m的是值是nil,并没有被初始化;读取nil 映射同读取空映射一样,但对nil映射进行写操作时会导致运行时错误,所以不要像上面那样初始化map,需要使用make函数:

m = make(map[string]int)

make函数会分配和初始化一个哈希映射数据结构,并返回一个指向该哈希映射的映射变量。相关数据结构细节由运行时实现,并且不因语言本身所规定。本文中我们将关注映射的使用,而不是他们的实现。

映射的使用

Go语言提供常见的映射使用语法,下面的声明是将键“route”赋值为66

m[“route”] = 66

这个声明是将值存储在键“route”下,返回并分配给新的变量i:

i := m[“route”]

如果返回的键不存在,我们得到值类型对应的零值 ;这个例子中值的类型是int类型,所以零值是0:

j := m[“root”]

// j == 0

len函数可以返回映射中条目的数量:

n := len(m)

delete函数可以删除映射中的一个条目:

delete(m, “route”)

delete函数不会返回任何值,如果特定的键不存在,那么将不会执行任何操作。

给一个已存在的键进行二值分配测试:

i, ok := m[“route”]

在这种情况下,第一个值(i)用于存储键“route”对应的值。如果这个键不存在,i的值是该类型的零值(0)。第二个值(ok)是布尔类型的值,如果被测试的键在映射中存在返回true,否则返回false。

如果不返回键的值,则第一个值使用下划线表示:

_, ok := m[“route”]

使用range关键字遍历映射中的内容:

for key, value := range m {

fmt.println(“Key:”, key, “Value:”, value)

}

使用映射字面量进行初始化::

commits := map [string] int {

“rsc” : 3711,

“r” : 2138,

“gri” : 1908,

“adg” : 912,

}

这种方法同样可以初始化一个空的映射,此时等价于make函数的功能相同:

m = map[string] int { }

零值的使用

当键不存在时,映射返回零值,这样处理是相当方便的。

像下面这个例子,一个值为布尔型的映射可以被用作集合来使用(布尔类型的零值为false)。这个例子是遍历Nodes链表并打印出他们的值。使用Node指针类型的映射来检测链表中的循环。

type Node struct {

Next *Node

Value interface{ }

}

var first *Node

visited := make(map[*Node]bool)

for n := first; n != nil; n = n.Next {

if visited[n] {

fmt.Println(“cycle detected”)

break

}

visited[n] = true

fmt.Println(n.Value)

}

这表明,如果检测到n,则visited[n]返回true,如果不存在,则返回false。在映射中没有必要使用2个值的形式去检测n是否存在;对于我们来说零值默认的。

另一个例子,展示了在切片类型的映射中零值的好处。向一个nil切片进行追加会创建一个新的slice,这等同于给切片类型的映射增加一个值;这种情况没有必要检查键是否存在。在接下来的例子中,切片people 被Person类型的值填充。每一个Person都有一个Name和一系列Likes。这个例子创建一个映射,将每个like的值 与一组喜欢它的people关联起来。

type Person struct {

Name string

Likes []string

}

var people []*Person

likes := make(map[string][]*Person)







请到「今天看啥」查看全文


推荐文章
江苏教育发布  ·  考研复试有变!划重点→
23 小时前
江苏教育发布  ·  考研复试有变!划重点→
23 小时前
包头晚报  ·  考研复试有变!
昨天
包头晚报  ·  考研复试有变!
昨天
如东新媒体  ·  分数线已公布!
3 天前
如东新媒体  ·  分数线已公布!
3 天前
钱币圈  ·  你适合玩古钱币吗?
7 年前
阿尔法工场研究院  ·  高善文:A股是个名利场
7 年前