我天真地尝试这样做:
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
这需要更高等级的生命周期,因为闭包中的生命周期不应该是类型签名的一部分:闭包只想接受&'a mut S任何生命周期'a(因为它需要使用仅保证持续内部的数据来调用函数)方法的next名称:外部没有任何可命名的内容),而不是类型签名中外部公开(并且在某种程度上可控)的生命周期。这是不可能的,但我已经看到 Niko Matsakis 在 IRC 上谈论了它的工作,并且有像#18837这样的准备性 Pull 请求,所以这希望很快就会出现。
需要明确的是:代码失败,因为next_只能使用生命周期至少为 的引用来调用'a,但&mut self.state生命周期只能为&mut self,除非'a声明为&'a mut self(这就是编译器建议它的原因)。添加此生命周期是非法的,因为它不满足特征声明的要求。
您现在可以使用旧的闭包来解决这个问题(这本质上就是Fn特征对象),甚至有一个标准库类型可以为您做到这一点:Unfold。
| 归档时间: |
|
| 查看次数: |
2442 次 |
| 最近记录: |