【问题标题】:How can I define a function that returns true if every value in an iterator is true?如果迭代器中的每个值都为真,我如何定义一个返回真的函数?
【发布时间】:2019-05-26 20:39:31
【问题描述】:

我想定义一个函数every,它接受一个迭代器,虽然它不是None,但要确保所有值都是true

示例应用:

every([true, true, true].into_iter()) == true
every([true, false, true].into_iter()) == false

我很难让它仅与Vec 一起工作,更不用说Iterator。我已经尝试了以下和一些变体,但没有得到任何结果。

use std::ops;

fn every<T>(v: Vec<T>) -> bool
where
    T: ops::Not,
{
    for item in v {
        match !item {
            T::No => return false,
        }
    }
    true
}

此代码得到错误:

error[E0599]: no associated item named `No` found for type `T` in the current scope
 --> src/lib.rs:9:13
  |
9 |             T::No => return false,
  |             ^^^^^ associated item not found in `T`

【问题讨论】:

标签: rust iterator


【解决方案1】:

一个基于Stargateur's comment的更通用的例子

fn every<T, I>(v: I) -> bool
where
    I: IntoIterator<Item = T>,
    T: std::ops::Not<Output = bool>,
{
    v.into_iter().all(|x| !!x)
}

(playground)

v 可以是任何实现IntoIterator 的东西,例如Vec,还有类似mapfilter,这使得这个解决方案非常通用。

【讨论】:

  • 是否可以将x 转换为布尔值而不是使用!!。我尝试了x as boolbool::from(x),但它们都不起作用。
  • 我接受了编译器的建议并使用了 trait bool: std::convert::From&lt;T&gt; instead of std::ops::Not&lt;Output = bool&gt;。这让我可以使用x.into() 而不是双重否定。两者似乎都适用于我的特定项目,我不知道在这种情况下哪种方法更好,或者它们是否等效。
  • @z.f.s !!x 是 C 语言中的一个习惯用法,用于将真整数转换为真正的 truefalse(如果仔细观察,它们只是 1 和 0)。 Rust 没有“真实性”(整数上的! 按位 NOT),所以我不会在这里使用它。事实上,如果你只打算在包含 bool 的迭代器上使用 every,我根本不会使 T 通用,但如果需要,我可能会选择 T: Borrow&lt;bool&gt; 来抽象引用。
  • 定义两个泛型类型when one will do
猜你喜欢
  • 2013-09-12
  • 2016-05-03
  • 2021-10-15
  • 2012-10-12
  • 2019-02-12
  • 2013-06-14
  • 1970-01-01
  • 2018-02-22
相关资源
最近更新 更多