[Go语言]实现可以枚举的map

在golang-nuts上看到有人问怎么样去枚举一个map。在go语言层面,并不支持支持枚举map,也就是说你不能获得一个枚举器在任意时刻去枚举这个map,只能用range一次性地遍历这个map。但是我们可以用map+list的方式来实现一个可以枚举的map。请看代码:
import (

"container/list"
"fmt"
)
type Iterator struct {

e *list.Element
}
func (p *Iterator) Valid() bool {

return p.e != nil
}
func (p *Iterator) Value() (int, int) {

pe := p.e.Value.(*Element)

return pe.k, pe.v
}
func (p *Iterator) Next() {

p.e = p.e.Next()
}
type Element struct {

k, v int
}
type ListMap struct {

m map[int]*list.Element
l *list.List
}
func NewListMap() *ListMap {

return &ListMap{


m: make(map[int]*list.Element),

l: list.New(),

}
}
func (p *ListMap) Set(k, v int) {

e, ok := p.m[k]
if ok {


e.Value.(*Element).v = v

} else {


p.m[k] = p.l.PushBack(&Element{k, v})

}
}
func (p *ListMap) Remove(k int) {

e, ok := p.m[k]
if ok {


delete(p.m, k)

p.l.Remove(e)

}
}
func (p *ListMap) Get(k int) (int, bool) {

e, ok := p.m[k]
if !ok {


return 0, false

}
return e.Value.(*Element).v, true
}
func (p *ListMap) Iterate() Iterator {

return Iterator{p.l.Front()}
}

使用的例子:

func main() {


m := NewListMap()

m.Set(1, 1)

m.Set(2, 2)

m.Set(3, 3)

m.Set(3, 300)

m.Remove(2)

it := m.Iterate()

for it.Valid() {



fmt.Println(it.Value())


it.Next()


}

}
输出:
1 1
3 300

说明:
为了达到更好的通用性,可以把key和value的类型都换成interface{}类型,但是会稍微损失一些性能。

一个思考题:
为什么go语言不直接提供枚举器或者枚举的方法呢?

原文发布于微信公众号 - Golang语言社区(Golangweb)

原文发表时间:2016-08-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

Java基础19(01)总结IO流,异常try…catch,throws,File类

1:异常(理解) (1)程序出现的不正常的情况。 (2)异常的体系 Throwable |--Error 严重问题,我们不处理。 |--Excepti...

43770
来自专栏desperate633

LintCode 单词切分题目分析

给出一个字符串s和一个词典,判断字符串s是否可以被空格切分成一个或多个出现在字典中的单词。

10920
来自专栏Python爬虫实战

LeetCode刷题:Array系列之Remove Element

#include <iostream> #include <vector> using namespace std;

8310
来自专栏封碎

BitSet位图算法 博客分类: 算法 算法IDEA

位图算法,使用bit存储数据并排序,优点是快速、占用资源少,缺点是只能对整数使用。     Java和C++中都有已经实现的的BitSet类,可以直接使用...

60840
来自专栏技术小黑屋

一个事半功倍的Java反射库

在Java和Android中,我们常常会使用反射来达到一些兼容的目的。Java原生提供的反射很是麻烦,使用起来很是不方便。比如我们想要调UserManager的...

14720
来自专栏desperate633

LeetCode 17. Letter Combinations of a Phone Number题目分析代码

以上的答案是按照词典编撰顺序进行输出的,不过,在做本题时,你也可以任意选择你喜欢的输出顺序。

8910
来自专栏PhpZendo

JavaScript ES6 (五) – 集合

本章我们将学习 ES6 中的 Set(集合) 及 WeakSet 集合 的相关用法及使用场景。

22310
来自专栏Java爬坑系列

【Java入门提高篇】Day19 Java容器类详解(二)Map接口

  上一篇里介绍了容器家族里的大族长——Collection接口,今天来看看容器家族里的二族长——Map接口。

282190
来自专栏Android知识点总结

Java容器源码攻坚战--第一战:Iterator

10910
来自专栏Java技术分享

使用beanUtils操纵javabean

package com.lan.beanutils; import java.lang.reflect.InvocationTargetExcepti...

23390

扫码关注云+社区

领取腾讯云代金券