7

在 Ruby 中迭代一个块非常简单——它干净利落地完成并继续执行其余代码。

另一方面,使用 Enumerator 进行迭代有点令人困惑。如果您在没有块的情况下调用 :each ,则会返回一个 Enumerator 。然后可以在 Enumerator 上调用 :next 以获取每个下一个迭代值。

然后奇怪的部分 - 当迭代完成时,而不是 Enumerator 返回 nil,它抛出一个异常:“迭代到达结束”。结果是它甚至没有返回值。

例如:

test = [ 'test_value' ]
enumerator = test.each
enumerator.next
>> "test_value"
enumerator.next
>> StopIteration: iteration reached at end

这样做的原因仅仅是因为枚举器可以返回 nil 值吗?答案只有在我发布此内容时才出现(所以我仍将发布它),但似乎必须如此。

如果是这样,这是处理此类问题的典型方式吗?使用异常来处理基本上按预期执行的代码似乎很奇怪。

4

2 回答 2

7

您是正确的,原因是nil枚举器可以将其作为有效值返回。为了回答您关于这是否是典型的问题,Python 使用一个也称为StopIteration.

>>> my_list = [1,2,3]
>>> i = iter(my_list)
>>> i.next()
1
>>> i.next()
2
>>> i.next()
3
>>> i.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

当然,大部分时间next都不会直接调用(each或使用for循环代替),因此这种底层机制不会经常暴露。

于 2010-07-09T15:39:38.860 回答
4

是的,nil 仍然是一个结果,这与没有返回值不同。这与尝试访问内存中不存在的变量或位置基本相同。这就是为什么你想要一个异常而不是返回一个 nil。听起来你想出来了:-)

于 2010-07-09T12:40:42.593 回答