提问人:thefrollickingnerd 提问时间:11/7/2023 更新时间:11/7/2023 访问量:47
地图闭合求和问题
Issue with summing over map closure
问:
我正在研究 AoC 来学习 Rust,并一直在尝试根据我看到的更有经验的 Rust 程序员编写的内容拼凑出一个解决方案。
下面似乎完全编译,除了我对 .sum() 有疑问。编译器指出,该状态更改为在求和运算之前。Iterator::Item
Result<usize, _>
我不知道我怎么会不使用结果类型。据我所知,sum 适用于迭代器,但它不认为结果类型是迭代器?get_priority
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`
答:
4赞
cdhowie
11/7/2023
#1
由于映射函数是易错的,因此需要一种错误聚合的方法。您可以使用 Iterator::try_fold
来执行此操作。在你的情况下,而不是你会做 ,这将返回 .如果映射函数返回 ,则将传播该错误,否则它将返回总和。.sum()
.try_fold(0, |a, b| a + b)
Result<usize, Box<dyn Error>>
Err
try_fold
Ok
2赞
Jmb
11/7/2023
#2
对类型的项目求和时,会得到相同类型的结果。但是在这里,您尝试将结果强制为普通.您需要:Result<usize, E>
usize
- 提供正确的类型
let result: Result<usize, Box<dyn Error>> = lines.map(|rucksack| { … }).sum();
- 删除类型注释,让编译器推断出正确的类型:
let result = lines.map(|rucksack| { … }).sum();
- 或者处理错误:
let result: usize = lines.map(|rucksack| { … }).sum().unwrap();
评论
0赞
cdhowie
11/8/2023
实现 的 TIL 。Result
Sum
评论
map
返回 for 项目类型 ,因为这是您返回的 。你可以把它变成一个像这样的向量,但是由于你想聚合它,你必须再次迭代它(例如)。我不确定你是否同意后者。希望它有助于获得一个想法,并希望其他人可以建议如何在不重复值的情况下实现它。Iterator
Result<usize, _>
Ok(..)
collect
.collect::<Result<Vec<usize>, _>>()?
.collect::<Result<Vec<usize>, _>>()?.iter().sum()
?