在折叠内部使用 if

Using if inside of fold

我需要计算 (bool, i32) 向量的长度,如果 bool 为真,我会增加计数。我正在使用折叠来执行此操作:

fn main() {
    let domain = [(true, 1), (false, 2), (true, 3)];
    let dom_count = domain.iter()
        .fold(0, |count, &(exists, _)| if exists {count + 1});
    println!("dom_count: {}", dom_count);
}

编译器抱怨说:

.fold(0, |count, &(exists, _)| if exists {count + 1})
                               ^^^^^^^^^^^^^^^^^^^^^ expected (), found integral variable

所以我添加了一个 ; 并得到了这个:

.fold(0, |count, &(exists, _)| if exists {count + 1;})
                               ^^^^^^^^^^^^^^^^^^^^^^ expected integral variable, found ()

如何在 fold 中正确使用 if 语句?

if 条件为 false 时,您尝试使用 什么值?

这是编译器首先告诉你的。因为没有 else 子句,缺失子句的 return 类型必须是 ()。由于 if 的真假分支必须具有相同的类型,因此真分支必须 return ()。但是,您的真实分支正在尝试 return 一个数字。

通过添加 ;,您使 if 的两个分支 return 编辑 (),然后失败,因为您的 fold 应该到return是一个整数。

一个解决方案是 return else 子句中的一个值:

fn main() {
    let domain = [(true, 1), (false, 2), (true, 3)];

    let dom_count = domain.iter()
        .fold(0, |count, &(exists, _)| {
            if exists {
                count + 1
            } else {
                count
            }
        });

    println!("dom_count: {}", dom_count);
}

fn main() {
    let domain = [(true, 1), (false, 2), (true, 3)];

    let dom_count = domain.iter()
        .fold(0, |count, &(exists, _)| {
            count + if exists {
                1
            } else {
                0
            }
        });

    println!("dom_count: {}", dom_count);
}

使用 filter:

更加地道
fn main() {
    let domain = [(true, 1), (false, 2), (true, 3)];

    let dom_count = domain.iter()
        .filter(|&&(exists, _)| exists)
        .fold(0, |count, _| count + 1);

    println!("dom_count: {}", dom_count);
}

并且计算项目数量的行为已经由 Iterator::count 处理:

fn main() {
    let domain = [(true, 1), (false, 2), (true, 3)];

    let dom_count = domain.iter().filter(|&&(exists, _)| exists).count();

    println!("dom_count: {}", dom_count);
}