地图闭合求和的问题

问题描述 投票:0回答:1

我正在 AoC 上学习 Rust,并一直在尝试根据我看到的更有经验的 Rust 程序员编写的内容拼凑出一个解决方案。 除了我对 .sum() 有问题之外,下面似乎完全可以编译。编译器指出在求和运算之前

Iterator::Item
更改为
Result<usize, _>

我不知道如何不使用

get_priority
中的结果类型。据我所知 sum 适用于迭代器,但它没有将结果类型视为迭代器?

fn main() {
    
    let data = fs::read_to_string("data/data.txt").expect("File should exist");
    let lines = data.lines(); // this is an iterator of lines (type &str)

    let result: usize = lines.map(|rucksack| {
        let (cmprt1, cmprt2) = rucksack.split_at(rucksack.len() / 2);
        let cmprt1: ByteSet = cmprt1.into();
        let cmprt2: ByteSet = cmprt2.into();
        let dup = cmprt1.intersection(cmprt2).first().ok_or("Error finding intersection")?;
        Ok(get_priorty(dup)?)
    }).sum();    
    println!("{}", result)
}

fn get_priorty(letter: u8) -> Result<usize, Box<dyn Error>>{
    match letter {
        b'a'..=b'z' => Ok(1 - (letter + b'a') as usize),
        b'A'..=b'Z' => Ok(27 - (letter + b'A') as usize),
        _ => Err("Unexpected character in rucksack".into())
    }
}

错误信息

10   |       let result: usize = lines.map(|rucksack| {
     |  _______________________________^
11   | |         let (cmprt1, cmprt2) = rucksack.split_at(rucksack.len() / 2);
12   | |         let cmprt1: ByteSet = cmprt1.into();
13   | |         let cmprt2: ByteSet = cmprt2.into();
14   | |         let dup = cmprt1.intersection(cmprt2).first().ok_or("Error finding intersection")?;
15   | |         Ok(get_priorty(dup)?)
16   | |     }).sum();    
     | |______^ `Iterator::Item` changed to `Result<usize, _>` here
note: required by a bound in `std::iter::Iterator::sum`
rust iterator closures
1个回答
0
投票

由于您的映射函数容易出错,因此您需要一种方法来进行错误聚合。您可以使用

Iterator::try_fold
来执行此操作。在您的情况下,您应该执行
.sum()
,而不是
.try_fold(0, |a, b| a + b)
,在这种情况下将返回
Result<usize, Box<dyn Error>>
。如果映射函数返回
Err
,则
try_fold
将传播该错误,否则它将返回
Ok
以及总和。

© www.soinside.com 2019 - 2024. All rights reserved.