我对Rust很新。我试图以代码的出现为借口来学习它。我目前是Elixir程序员,所以我整天使用map / reduce。
我努力做同样生锈的事情。我确定我可以保释迭代器,只需用for loops
进行犁,但我不愿意。
看起来fold
与reduce
非常相似,但我无法弄清楚如何使用比整数更复杂的状态。
input
.chars()
.map(|c| c.to_digit(10).unwrap())
.fold(initial_state, |state, &x| {
let Day1{sum: sum, prev: prev} = state;
Some(Day1{
sum: sum,
prev: prev,
});
})
我收到很多关于非匹配类型的编译器错误。
.fold(initial_state, |state, &x| {
^^^^^^^^^^^^^ expected (), found struct `Day1`
let Day1{sum: sum, prev: prev} = state;
^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found struct `Day1`
为什么期望()
没什么(我认为)。我想了解错误,但如果有更好的方法让状态保持在循环中,我也希望得到一些帮助。
答案 0 :(得分:1)
如果你看看你在做什么,问题就很明显了。让我解释一下。
首先,让Rust文档保持联系是个好主意。查看std::iter::Iterator::fold
方法会给出它的签名:
fn fold<B, F>(self, init: B, f: F) -> B where
F: FnMut(B, Self::Item) -> B,
有3个参数:self
你没有触及,因为你使用这个方法作为结构方法而不是静态方法,init
你设置为initial_state
和折叠功能为f
。一眼就可以说一切都是正确的,但你的用法与这个原型不匹配,因为在fold函数结束时多余的分号 - 在这种情况下你的整个表达式会返回()
,因此编译器会尝试匹配返回类型你的折叠函数具有init
参数的类型,它无法做到这一点。解决方案非常简单:通过更改
let Day1 { sum: sum, prev: prev } = state;
Some(Day1 {
sum: sum,
prev: prev,
});
到此:
let Day1 {sum: sum, prev: prev} = state;
Some(Day1 {
sum: sum,
prev: prev,
})
在Rust中(与大多数函数式语言一样),最后一个表达式是返回表达式。在您的情况下,您只返回了分号,但是如果删除分号,则会返回Some(Day1 { sum: sum, prev: prev })
类型为Option<Day1>
的表达式。
解决此问题后,您可能会遇到另一个问题:Day1
和Option<Day1>
不匹配,因为您再次使用不同的类型:initial_state
类型Day1
和折叠返回Option<Day1>
的函数。解决方案是在任何这些地方使用相同的类型,例如,使用类型initial_state
的make Option<Day1>
或从fold函数返回Day1
对象,这样一切都将编译。再次,让Rust文档与您联系可以获得clear example of the .fold
usage。