如何将结构或元组置于生锈迭代器的状态?

时间:2017-12-02 06:20:47

标签: rust

我对Rust很新。我试图以代码的出现为借口来学习它。我目前是Elixir程序员,所以我整天使用map / reduce。

我努力做同样生锈的事情。我确定我可以保释迭代器,只需用for loops进行犁,但我不愿意。

看起来foldreduce非常相似,但我无法弄清楚如何使用比整数更复杂的状态。

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`

为什么期望()没什么(我认为)。我想了解错误,但如果有更好的方法让状态保持在循环中,我也希望得到一些帮助。

1 个答案:

答案 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>的表达式。

解决此问题后,您可能会遇到另一个问题:Day1Option<Day1>不匹配,因为您再次使用不同的类型:initial_state类型Day1和折叠返回Option<Day1>的函数。解决方案是在任何这些地方使用相同的类型,例如,使用类型initial_state的make Option<Day1>或从fold函数返回Day1对象,这样一切都将编译。再次,让Rust文档与您联系可以获得clear example of the .fold usage