У меня есть две разные структуры. Основной, 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))
В вашем примере, пожалуйста, добавьте пример использования вашего SFunction - я считаю, что это поможет нам лучше понять, что вы намереваетесь делать. – llogiq
Этот вопрос имеет тот же диагноз, причину и решение, что и ваш [предыдущий вопрос] (http://stackoverflow.com/q/32879649/155423): используйте 'FnOnce'. – Shepmaster