做所有? 还有什么? 保证短路评估?
在pry
和irb
测试一些代码,我得到以下结果:
[1] pry(main)> a = [1, 3, 5, 7, 0] => [1, 3, 5, 7, 0] [2] pry(main)> a.any? {|obj| p obj; 3 / obj > 1} 1 => true [3] pry(main)> a.all? {|obj| p obj; 3 / obj > 1} 1 3 => false
在[2]
和[3]
我看到似乎存在短路评估,尽快中止迭代,但是这种保证行为是什么? 阅读文档没有提到这种行为。 我意识到我可以使用inject
,因为它将迭代所有内容,但我有兴趣找出官方的Ruby视图是什么。
是。
在Ruby标准的最终草案中, all?
定义如下:
- 在接收器上调用
each
方法 - 对于每个方法的
each
元素X:- 如果给出了块,则以X为参数调用块。 如果此调用返回falseish对象,则返回 false 。
- 如果未给出块,并且X是假的对象,则返回 false 。
- 回归真实 。
注意步骤2中的返回字。这可以保证短路评估。 any?
是类似的定义。 然而,该标准仍然是草案,我不知道哪些Ruby实现(如果有的话)旨在符合标准。
any?
方法只是在Enumerable
实现’ 或 ‘逻辑function。 它可以解释为声明:
y = x1 v x2 v x3 v … v xn
而这all?
方法在Enumerable
实现’ 和 ‘逻辑function。 它也可以解释为声明:
y = x1 * x2 * x3 * … * xn
由于Array
是Enumerable
,它还包括那些方法。 那么,对于any?
方法any?
第一次出现的true
(确切地说既不是nil
也不是false
)结果打破了枚举的true
结果。 例如,在数字4上 , yielding变为true ,因此方法会中断执行返回true
:
[1,2,3,4,5].any? {| x | puts x ; x > 3 } # 1 # 2 # 3 # 4 # => true
您还可以将DeMorgan的规则应用于该函数any?
,并使用all?
方法:
![1,2,3,4,5].all? {| x | puts x ; x <= 3 } # 1 # 2 # 3 # 4 # => true
对于方法all?
false
或nil
结果的第一个偶然事件做类似的事情,即返回false
。 在示例中,数字3上的yielding变为false ,因此方法会中断执行返回false
:
[1,2,3,4,5].all? {| x | puts x ; x < 3 } # 1 # 2 # 3 # => false
而DeMorgan的改造使用了any?
方法:
![1,2,3,4,5].any? {| x | puts x ; x >= 3 } # 1 # 2 # 3 # => false