cpc*_*len 6 dictionary iterator go
我正在编写一个迭代映射中的条目的函数。我希望能够干净地处理迭代时从地图中添加或删除的项目,就像for k, v := range myMap { //...
所做的那样,但我每次迭代只处理一个键/值对,所以我不能使用范围。我想要这样的东西:
func processItem(i iterator) bool {
k, v, ok := i.next()
if(!ok) {
return false
}
process(v)
return true
}
var m = make(map[string]widget)
// ...
i := makeIterator(m)
for processItem(i) {
// code which might add/remove item from m here
}
Run Code Online (Sandbox Code Playgroud)
我知道 range 使用 ' hiter
' 结构体和关联函数(如 中定义src/runtime/hashmap.go
)来执行迭代。有没有什么方法可以访问这个迭代器作为一个具体化的(一流的)Go 对象?
是否有另一种迭代映射的策略可以很好地处理插入/删除,但提供一流的迭代器对象?
额外问题:是否有另一种迭代映射的策略,该策略还可以处理映射和迭代器被序列化到磁盘然后恢复的情况,迭代从停止的地方继续?(显然内置迭代range
器不具备这个能力!)
您可以使用通道作为迭代器。
您的迭代器将是一个返回通道的函数,该通道将当前迭代值传达给接收它的人:
func iterator(m map[string]widget) chan iteration {
c := make(chan iteration)
go func() {
for k,v := range m {
c <- iteration{k,v}
}
close(c)
}()
return c
}
Run Code Online (Sandbox Code Playgroud)
这当然不是通用的,您可以使用interface{}
和/或反射使其通用,但如果您确实需要它,那应该不会太难。在迭代结束时关闭通道将通知迭代结束,稍后演示。
类型iteration
就在那里,因此您可以同时发送键和值,它看起来像这样:
type iteration struct {
key string
value widget
}
Run Code Online (Sandbox Code Playgroud)
有了这个,你就可以这样做(在游戏中):
m := map[string]widget{"foo": widget{3}, "bar": widget{4}}
i := iterator(m)
iter, ok := <- i
fmt.Println(iter, ok)
iter, ok = <- i
fmt.Println(iter, ok)
iter, ok = <- i
fmt.Println(iter, ok)
Run Code Online (Sandbox Code Playgroud)
这产生
{foo {3}} true
{bar {4}} true
{ {0}} false
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1650 次 |
最近记录: |