Rust 如何指定依赖于单独类型中借用的闭包绑定的生存期?

Rust 如何指定依赖于单独类型中借用的闭包绑定的生存期?,rust,lifetime,Rust,Lifetime,我有两种类型:Lexer和SFunction SFunction代表有状态函数,定义如下: struct SFunction { f: Option<Box<FnMut() -> SFunction>>, } 如何在代码中指定此生存期要求 我收到的编译器错误是“由于需求冲突,无法通过闭包推断出捕获self的合适生存期”。我很确定这里的“冲突需求”是框类型假定生存期为静态。我可以做一些类似于Box SFunction+'a>的事情,其中'a是由它所依赖的

我有两种类型:
Lexer
SFunction

SFunction
代表有状态函数,定义如下:

struct SFunction {
    f: Option<Box<FnMut() -> SFunction>>, 
}

如何在代码中指定此生存期要求

我收到的编译器错误是“由于需求冲突,无法通过闭包推断出捕获
self
的合适生存期”。我很确定这里的“冲突需求”是
类型假定生存期为
静态
。我可以做一些类似于
Box SFunction+'a>
的事情,其中
'a
是由它所依赖的Lexer定义的生命周期,但我不确定如何定义这样的
'a


谢谢你的帮助

问题出在这一行:

SFunction::new(Box::new(|| f(self)))
在这里,
self
是对
Lexer
的引用,但不能保证Lexer的寿命足够长。事实上,它需要在
静态的
生命周期中生存!如果未指定生存期,装箱的trait对象将使用静态生存期。在代码中,这两个声明是等价的:

<Box<FnMut() -> SFunction>>
<Box<FnMut() -> SFunction> + 'static>
当然,您是否会有一个具有静态生存期的
Lexer
,这是非常值得怀疑的,因为这意味着它正在对静态数据进行Lexer,这不是很有用。这意味着我们需要在你的特质对象中包含生命周期。。。正如你所建议的

最终,有助于发现问题的是稍微调整一下关闭:

fn sfunction(&mut self, f: fn(&mut Lexer) -> SFunction) -> SFunction {
    SFunction::new(Box::new(move || {
        // f(self)
        let s2 = self;
        let f2 = f;
        f2(s2)
    }))
}
编译此文件会产生一个错误,指出真正的问题:


我希望我的解释是正确的,并且更改后的代码仍然适合您的用例

这似乎很有效——我明白为什么
FnMut
不起作用。我在将函数放入框后调用它时遇到问题。看起来这可能只是锈病中不可能发生的事情?@Kites是的,很遗憾,这有点复杂。有一些方法可以解决这个问题,但我不清楚它们的稳定性。这就是我所看到的:/--感谢链接!
fn lex(&'static mut self) {
    self.sfunction(Lexer::lex_normal).call()
}

fn sfunction(&'static mut self, f: fn(&mut Lexer) -> SFunction) -> SFunction {
    SFunction::new(Box::new(move || f(self)))
}
fn sfunction(&mut self, f: fn(&mut Lexer) -> SFunction) -> SFunction {
    SFunction::new(Box::new(move || {
        // f(self)
        let s2 = self;
        let f2 = f;
        f2(s2)
    }))
}
<anon>:31:22: 31:26 error: cannot move out of captured outer variable in an `FnMut` closure [E0507]
<anon>:31             let s2 = self;
                               ^~~~
<anon>:31:17: 31:19 note: attempting to move value to here
<anon>:31             let s2 = self;
                          ^~
<anon>:31:17: 31:19 help: to prevent the move, use `ref s2` or `ref mut s2` to capture value by reference
struct SFunction<'a> {
    f: Option<Box<FnOnce() -> SFunction<'a> + 'a>>, 
}

impl<'a> SFunction<'a> {
    fn new(f: Box<FnOnce() -> SFunction<'a> + 'a>) -> SFunction<'a> {
        SFunction {
            f: Some(f),
        }
    }

    fn empty() -> SFunction<'a> {
        SFunction {
            f: None,
        }
    }

    fn call(self) { }
}

struct Lexer;

impl Lexer {
    fn lex(&mut self) {
        self.sfunction(Lexer::lex_normal).call()
    }

    fn sfunction(&mut self, f: fn(&mut Lexer) -> SFunction) -> SFunction {
        SFunction::new(Box::new(move || f(self)))
    }

    fn lex_normal<'z>(&'z mut self) -> SFunction<'z> {
        SFunction::empty()
    }
}

fn main() {
    let mut l = Lexer;
    l.lex()
}