如何正确处理复杂的递归生命周期?

How does one properly handle complex recursive lifetimes?

我有两个不同的结构。主要的 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))

问题是 do_something(&'a mut self) 借用了 self 并且在完成之前不会释放它。但是您的盒装闭包是 "promising" 以保持 do_something 可多次调用,这是不可能的(因为第一次调用将 "lock" self)。

或者你可以从 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 而不是 Shepmaster 评论的 FnMut。请注意,在这种情况下,您正在移动 self 的所有权而不是借用,并且您承诺只调用一次闭包。

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() {}