2010-07-09 65 views
6

在Ruby中对块进行迭代非常简单 - 它干净地完成并继续执行其余的代码。Ruby Enumerator - 为什么以异常结束?

另一方面,使用枚举器进行迭代更容易混淆。如果你调用:每一个都没有块,​​则返回一个枚举器。 :接下来可以在枚举器上调用以获取每个下一个迭代值。

然后当迭代完成,而不是枚举返回无奇兼职,它抛出一个异常:“在迭代结束时达到”。结果是它甚至不返回一个值。

例如:

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

简直让零值可以通过枚举器返回的原因呢?答案只发生在我发布这个(所以我会发布它仍然),但似乎一定是这种情况。

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

回答

6

你是正确的,其原因在于,这样可以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循环),从而这个潜在的机制不被暴露,往往。

+1

OCaml的走得更远 - 红宝石的'散列的更多或更少的当量[键]'('List.assoc键hash')引发一个例外('Not_found')如果密钥不表示。这实际上是非常合乎逻辑的 - 当你调用':next'时,你期望的“正常”是获得下一个值。 *不*获得下一个值显然是一种特殊情况。 – Amadan 2010-07-09 15:47:20

+1

@Amadan:如果找不到密钥,'hash.fetch(key)'会引发一个'KeyError'。 – 2010-07-09 17:17:02

+0

有趣的说法阿马丹 - 我买了它。 – Asher 2010-07-10 02:41:47

3

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