在折叠内使用if

时间:2016-11-28 02:35:06

标签: if-statement rust 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 ()

如何正确使用if内的fold声明?

1 个答案:

答案 0 :(得分:3)

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

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

通过添加;,您可以使if的两个分支都返回(),然后由于fold 假设返回一个整数。

一种解决方案是在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);
}