Ruby 枚举器 - 为什么会出现异常?

发布于 2024-09-08 15:45:17 字数 523 浏览 7 评论 0原文

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

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

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

例如:

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

这样做的原因仅仅是为了让枚举器可以返回 nil 值吗?只有当我发布这篇文章时,我才会想到答案(所以我仍然会发布它),但似乎情况一定如此。

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

Iterating a block in Ruby is simple enough - it finishes cleanly and proceeds on to the rest of the code.

Iterating with an Enumerator, on the other hand, is a bit more confusing. If you call :each without a block, an Enumerator is returned instead. :next can then be called on the Enumerator to get each next iterative value.

And then the odd part- when iteration is complete, instead of the Enumerator returning nil, it throws an exception: "iteration reached at end". The result is that it doesn't even return a value.

For instance:

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

Is the reason for this simply so that nil values can be returned by the Enumerator? The answer occurs to me only as I post this (so I am going to post it still), but seems like it must be the case.

If that is so, is this a typical way of handling such issues? It seems odd to use an Exception to handle code that essentially performs as expected.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

反目相谮 2024-09-15 15:45:17

您是对的,原因是枚举器可以将 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 循环来代替),所以这个底层机制是'不经常暴露。

You are correct that the reason is so that nil can be returned as a valid value by the Enumerator. To answer your question of whether this is typical, Python handles it in the same way using an exception also called 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

Of course, most of the time next isn't called directly (each or a for loop being used instead) so this underlying mechanism isn't exposed that often.

↙温凉少女 2024-09-15 15:45:17

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

Yeah, nil is still a result, which is different than not having a value to return. It's basically the same as trying to access a variable or a location in memory that's not there. This is why you want an exception rather than returning a nil. Sounds like you figured that out :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文