Ruby Enumerator - 为什么要完成异常?

时间:2010-07-09 12:27:34

标签: ruby exception enumerator

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

另一方面,使用枚举器进行迭代会更加混乱。如果您调用:每个没有块,则返回枚举器。 :然后可以在Enumerator上调用next来获取每个下一个迭代值。

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

例如:

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

这样做的原因是,枚举器可以返回零值吗?答案发生在我身上,因为我发布了这个(所以我要发布它),但似乎一定是这样。

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

2 个答案:

答案 0 :(得分: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不是直接调用的(eachfor循环被替代使用)所以这种基础机制不会经常暴露。< / p>

答案 1 :(得分:4)

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