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

标签 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,));
    }
}

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

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

<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

我不明白这个错误。

闭包应该使用生命周期 'a 作为参数,这是结构的生命周期。

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

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

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

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

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

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

最佳答案

这需要 higher-rank lifetimes ,因为闭包中的生命周期不应该是类型签名的一部分:闭包只想获取 &'a mut S任何 生命周期内 'a (因为它需要使用仅保证在 next 方法内部持续的数据调用函数:外部没有可命名的),而不是在类型签名中从外部暴露(并且在某种程度上可控)的生命周期。这是不可能的,但我看到 Niko Matsakis 在 IRC 上谈论关于它的工作,并且有像 #18837 这样的准备性拉取请求。所以这有望很快出现。

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

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

关于rust - 如何使用 Rust 中的闭包创建迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26860905/

相关文章:

rust - 删除通过出指针发送到C然后传回Rust进行删除的mem::forgotten字符串数组的正确方法是什么?

Rust 借用/所有权

rust - 由于多次使用 `use std::{fs::self, io::self}`,无法写入 `self`

rust - 警告[E0502] : cannot borrow `c` as immutable because it is also borrowed as mutable

assembly - 尝试通过 int 16h 读取 key 以 VM 重启结束

struct - 如何将函数作为结构中的成员

json - 如何使用 Serde 反序列化包含空值的 JSON 文件?

rust - 返回自定义结果时如何解析 "expected (), found Result"?

rust - 缺少终身运营商

macros - 如何在宏中命名任意序列的事物?