如何使用 Rust 中的闭包创建迭代器?

Dou*_*oug 6 rust

我天真地尝试这样做:

struct Foo<'a, S: Send, T:Send> {
    next_:Box<Fn<(&'a mut S,), Option<T>> + Send>,
    state:S
}

impl<'a, S: Send, T: Send> Iterator<T> for Foo<'a, S, T> {
    fn next(&mut self) -> Option<T> {
        return self.next_.call((&mut self.state,));
    }
}
Run Code Online (Sandbox Code Playgroud)

要创建迭代器,我可以使用闭包轻松发送到任务。

然而,它会产生可怕的生命周期不匹配错误:

<anon>:8:33: 8:48 error: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
<anon>:8         return self.next_.call((&mut self.state,));
                                         ^~~~~~~~~~~~~~~
<anon>:7:5: 9:6 help: consider using an explicit lifetime parameter as shown: fn next(&'a mut self) -> Option<T>
<anon>:7     fn next(&mut self) -> Option<T> {
<anon>:8         return self.next_.call((&mut self.state,));
<anon>:9     }
error: aborting due to previous error
playpen: application terminated with error code 101
Run Code Online (Sandbox Code Playgroud)

我不明白这个错误。

闭包应该接受一个带有生命周期“a”的参数,这是结构体的生命周期。

状态由结构拥有,因此它的生命周期为“a”。

使用 next_.call((&mut self.state,)) 不会调用任务;它应该只在 call() 的持续时间内有效,据我所知,这应该是有效的。

所以这里的不匹配是在 next() 中的 self 生命周期和调用中的 'a 之间......但我不明白为什么它不会是 'a。

修复上述代码的正确方法是什么?

有没有更好的方法来做到这一点?

婴儿围栏: http: //is.gd/hyNi0S

huo*_*uon 3

这需要更高等级的生命周期,因为闭包中的生命周期不应该是类型签名的一部分:闭包只想接受&'a mut S任何生命周期'a(因为它需要使用仅保证持续内部的数据来调用函数)方法的next名称:外部没有任何可命名的内容),而不是类型签名中外部公开(并且在某种程度上可控)的生命周期。这是不可能的,但我已经看到 Niko Matsakis 在 IRC 上谈论了它的工作,并且有像#18837这样的准备性 Pull 请求,所以这希望很快就会出现。

需要明确的是:代码失败,因为next_只能使用生命周期至少为 的引用来调用'a,但&mut self.state生命周期只能为&mut self,除非'a声明为&'a mut self(这就是编译器建议它的原因)。添加此生命周期是非法的,因为它不满足特征声明的要求。

您现在可以使用旧的闭包来解决这个问题(这本质上就是Fn特征对象),甚至有一个标准库类型可以为您做到这一点:Unfold