- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我无法准确理解 ruby 可枚举对象保留了多少状态。我知道一些 python,所以我期待在我从可枚举的项目中取出一个项目后,它就消失了,下一个项目将在我拿另一个项目时返回。奇怪的是,当我使用 next
时会发生这种情况,但当我使用 take
of first
时不会发生这种情况。这是一个例子:
a = [1,2,3].to_enum
# => #<Enumerator: [1, 2, 3]:each>
a.take(2)
# => [1, 2]
a.next
# => 1
a.next
# => 2
a.take(2)
# => [1, 2]
a.next
# => 3
a.next
# StopIteration: iteration reached an end
# from (irb):58:in `next'
# from (irb):58
# from /usr/bin/irb:12:in `<main>'
a.take(2)
# => [1, 2]
似乎枚举在 next
调用之间保持状态,但在每次 take
调用之前重置?
最佳答案
这可能有点令人困惑,但重要的是要注意在 Ruby 中有 Enumerator
类和 Enumerable
模块。
Enumerator
类包括Enumerable
(像大多数可枚举对象,如Array
、Hash
等。
next
方法作为 Enumerator
的一部分提供,它确实具有内部状态。您可以认为 Enumerator
非常接近其他语言公开的 Iterator
的概念。
当您实例化枚举器时,内部指针指向集合中的第一项。
2.1.5 :021 > a = [1,2,3].to_enum
=> #<Enumerator: [1, 2, 3]:each>
2.1.5 :022 > a.next
=> 1
2.1.5 :023 > a.next
=> 2
这不是 Enumerator 的唯一目的(否则它可能被称为 Iterator
)。但是,这是已记录的功能之一。
An Enumerator can also be used as an external iterator. For example, #next returns the next value of the iterator or raises StopIteration if the Enumerator is at the end.
e = [1,2,3].each # returns an enumerator object.
puts e.next # => 1
puts e.next # => 2
puts e.next # => 3
puts e.next # raises StopIteration
但正如我之前所说,Enumerator
类包括Enumerable
。这意味着 Enumerator
的每个实例都公开了旨在处理集合的 Enumerable
方法。在本例中,集合是 Enumerator
所在的集合。
take
是一个通用的 Enumerable
方法。它旨在返回 enum
的前 N 个元素。请务必注意,enum
指的是任何包含 Enumerable
的通用类,而不是 Enumerator
。因此,take(2)
将返回集合的前两个元素,而不管指针在 Enumerator
实例中的位置。
让我给你看一个实际的例子。我可以创建一个自定义类,并实现 Enumerable
。
class Example
include Enumerable
def initialize(array)
@array = array
end
def each(*args, &block)
@array.each(*args, &block)
end
end
我可以混合使用 Enumerable
,只要我为 each
提供一个实现,我就可以免费获得所有其他方法,包括 take
.
e = Example.new([1, 2, 3])
=> #<Example:0x007fa9529be760 @array=[1, 2, 3]>
e.take(2)
=> [1, 2]
正如预期的那样,take
返回前 2 个元素。 take
忽略我实现的任何其他内容,与 Enumerable
完全一样,包括状态或指针。
关于Ruby 可枚举重置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28438888/
我是一名优秀的程序员,十分优秀!