为什么Iterator :: all对于空迭代器都返回true?

时间:2018-01-14 09:45:02

标签: rust

以下代码

fn main() {
    {
        let a: Vec<i32> = vec![1, 2, 3, 4];
        print!("{}\n", a.into_iter().all(|x| x > 1));
    }
    {
        let a: Vec<i32> = vec![];
        print!("{}\n", a.into_iter().all(|x| x > 1));
    }
}

给我输出

false
true

令人惊讶的是,a.into_iter().all(|x| x > 1)true为空时返回a

查看the docs for Iterator::all,我看到它已明确说明:

  

空迭代器返回true。

为什么选择这样做?

2 个答案:

答案 0 :(得分:12)

这是几乎所有编程语言中all函数的典型约定,除了那些错误的函数。相反,any会为空序列返回false

原因是它对典型场景更有用。如果您有一个需求列表,并且值必须满足所有这些要求才能通过过滤器。如果您的列表实际上是空的,那么值是否应该通过?通常最有意义的答案是肯定的。因此,conditions.all(|value| condition.fulfilled(value))会为空列表返回true

这也是all定义重新制定的自然结果,&#34;没有项目是假的&#34;,如果你以直观的方式实现all,则是默认的:

fn all<F>(&mut self, f: F) -> bool
where
    F: FnMut(Self::Item) -> bool,
{
    for v in self {
        if !f(v) {
            return false;
        }
    }
    return true;
}

在这方面甚至可能有数学基础,但我无法快速找到答案。

答案 1 :(得分:3)

如果您对数学基础感兴趣,这里有一个简短的证据:

声明A => B(A暗示B)在逻辑上等同于!A | B(不是A或B)。

声明Sfor each x in X, P(x) is true(其中P是谓词)是for each x: x in X implies P(X) is true的简写。

因此该陈述相当于:For each x: P(x) is true or x is not in X

如果X为空,则语句x is not in X始终为true,因此语句S为真。