我有两种不同的结构。主要的Example
和一个包含递归类型函数的函数SFunction
。
这是他们的样子:
struct Example {
text: String,
}
impl<'a> Example {
fn function(&'a mut self) -> SFunction<'a> {
let closed_function = move || self.do_something();
SFunction::new(Box::new(closed_function))
}
fn do_something(&'a mut self) -> SFunction<'a> {
SFunction::empty()
}
}
struct SFunction<'a> {
f: Option<Box<FnMut() -> SFunction<'a> + 'a>>,
}
impl<'a> SFunction<'a> {
fn new(f: Box<FnMut() -> SFunction<'a> + 'a>) -> SFunction<'a> { // or no 'a on store
SFunction { f: Some(f) }
}
fn empty() -> SFunction<'a> {
SFunction { f: None }
}
}
(Here is a version in the Rust Playground)
这不能编译,但我很困惑为什么会这样。我确定它与递归类型函数有关,因为整个闭包的东西是在没有那个部分的情况下编译的。
以下是错误消息:
src/main.rs:34:45: 34:59 error: cannot infer an appropriate lifetime for autoref due to conflicting requirements
src/main.rs:34 let closed_function = move || self.do_something();
^~~~~~~~~~~~~~
note: in expansion of closure expansion
src/main.rs:34:32: 34:59 note: expansion site
src/main.rs:34:40: 34:59 note: first, the lifetime cannot outlive the lifetime as defined on the block at 34:39...
src/main.rs:34 let closed_function = move || self.do_something();
^~~~~~~~~~~~~~~~~~~
src/main.rs:34:40: 34:44 note: ...so that closure can access `self`
src/main.rs:34 let closed_function = move || self.do_something();
^~~~
note: in expansion of closure expansion
src/main.rs:34:32: 34:59 note: expansion site
src/main.rs:33:49: 36:7 note: but, the lifetime must be valid for the lifetime 'a as defined on the block at 33:48...
src/main.rs:33 fn function(&'a mut self) -> SFunction<'a> {
src/main.rs:34 let closed_function = move || self.do_something();
src/main.rs:35 SFunction::new(Box::new(closed_function))
src/main.rs:36 }
src/main.rs:35:10: 35:51 note: ...so that expression is assignable (expected `SFunction<'a>`, found `SFunction<'_>`)
src/main.rs:35 SFunction::new(Box::new(closed_function))
答案 0 :(得分:2)
问题是do_something(&'a mut self)
借用了自己,并且在完成之前不会释放它。但你的盒装封口是'#34;承诺&#34;保持do_something
可多次调用,这是不可能的(因为第一次调用将&#34;锁定&#34;自我)。
您可以从do_something
删除对self的依赖:
impl Example {
fn function<'a>(&'a mut self) -> SFunction<'a> {
let closed_function = move || do_something();
SFunction::new(Box::new(closed_function))
}
}
fn do_something<'a>() -> SFunction<'a> {
SFunction::empty()
}
或者您使用FnOnce
代替FnMut
,因为Shepmaster发表了评论。请注意,在这种情况下,您将移动自己的所有权而不是借用,并且您承诺只会调用一次关闭。
struct Example {
text: String,
}
impl Example {
fn function<'a>(self) -> SFunction<'a> {
let closed_function = move || self.do_something();
SFunction::new(Box::new(closed_function))
}
fn do_something<'a>(self) -> SFunction<'a> {
SFunction::empty()
}
}
struct SFunction<'a> {
f: Option<Box<FnOnce() -> SFunction<'a> + 'a>>,
}
impl<'a> SFunction<'a> {
fn new(f: Box<FnOnce() -> SFunction<'a> + 'a>) -> SFunction<'a> { // or no 'a on store
SFunction { f: Some(f) }
}
fn empty() -> SFunction<'a> {
SFunction { f: None }
}
}
fn main() {}