首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Enumerator#each重新启动序列

Enumerator#each重新启动序列
EN

Stack Overflow用户
提问于 2013-05-06 02:12:22
回答 2查看 192关注 0票数 3

我很惊讶Enumerator#each没有从序列中的当前位置开始。

代码语言:javascript
复制
o = Object.new

def o.each
  yield 1
  yield 2
  yield 3
end

e = o.to_enum
puts e.next
puts e.next
e.each{|x| puts x}
# I expect to see 1,2,3 but I see 1,2,1,2,3
# apparently Enumerator's each (inherited from Enumerable) restarts the sequence!

我做错了吗?有没有一种方法可以构造另一个枚举器(来自e),使其具有预期的每个行为?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-06 03:41:40

您没有做错,只是这不是为Enumerator#each定义的语义。您可以创建一个派生枚举器,它只从当前位置迭代到末尾:

代码语言:javascript
复制
class Enumerator
  def enum_the_rest
    Enumerator.new { |y| loop { y << self.next } }
  end
end

o = Object.new
def o.each
  yield 1
  yield 2
  yield 3
end

e = o.to_enum
=> #<Enumerator: ...>
e.next
=> 1
e2 = e.enum_the_rest
=> #<Enumerator: ...>
e2.each { |x| puts x }
=> 2
=> 3

顺便说一句,each不会重新启动序列,它只是在整个范围内运行。您的枚举器仍然知道它相对于下一次next调用的位置。

代码语言:javascript
复制
e3 = o.to_enum
e3.next
=> 1
e3.next
=> 2
e3.map(&:to_s)
=> ["1", "2", "3"]
e3.next
=> 3
票数 3
EN

Stack Overflow用户

发布于 2013-05-06 03:48:46

Enumerator#nextEnumerator#each在对象上的工作方式不同。根据#each的文档(重点是我的):

根据此枚举数的构造方式遍历块。如果未给出块,则返回self。

因此,#each的行为始终基于原始设置,而不是当前的内部状态。如果您在源代码方面很快达到顶峰,您将看到rb_obj_dup被调用来设置一个新的枚举器。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16387530

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档