尽管受到限制,价值仍然不够长

时间:2016-07-12 22:17:37

标签: compiler-errors closures rust lifetime

以下Rust代码无法编译:

pub struct UserAction<'u> {
    _act: &'u mut (FnMut() + 'u)
}

impl<'u, F: FnMut() + 'u> From<F> for UserAction<'u> {
    fn from(f: F) -> Self {
        UserAction { _act: (&mut f) as &'u mut (FnMut() + 'u) }
    }
}

我从rustc 1.10稳定得到的错误是:

lives.rs:7:38: 7:39 error: `f` does not live long enough
lives.rs:7             UserAction { _act: (&mut f) as &'u mut (FnMut() + 'u) }
                                                ^
lives.rs:6:31: 8:10 note: reference must be valid for the lifetime 'u as defined on the block at 6:30...
lives.rs:6         fn from(f: F) -> Self {
                                         ^
lives.rs:6:31: 8:10 note: ...but borrowed value is only valid for the scope of function body at 6:30
lives.rs:6         fn from(f: F) -> Self {
                                         ^
error: aborting due to previous error

我不确定为什么这是一个错误;类型F至少与生命周期'u一样长,因为它受限于。我缺少什么,我该如何解决这个错误?

2 个答案:

答案 0 :(得分:3)

作为mcarton says,您将闭包的所有权传递给函数,然后尝试对其进行引用。感到高兴的是,编译器发现错误,并阻止您使用引用内存损坏的某些超出范围的变量的引用。

限制F: FnMut() + 'u声明F必须是实现FnMut特征的类型,包含的参考比生命周期'u更长。它并没有说F本身必须比那一辈子寿命更长。实际上,我们可以看到f在方法退出后没有所有者,因此它的生命周期结束 - 因此错误。

应该使用的最直接的等价物是使用盒装特征对象而不是特征对象引用

pub struct UserAction<'u> {
    _act: Box<FnMut() + 'u>,
}

impl<'u, F: FnMut() + 'u> From<F> for UserAction<'u> {
    fn from(f: F) -> Self {
        UserAction { _act: Box::new(f) }
    }
}

另一种替代方法是渗透泛型类型:

pub struct UserAction<F> {
    _act: F,
}

impl<F: FnMut()> From<F> for UserAction<F> {
    fn from(f: F) -> Self {
        UserAction { _act: f }
    }
}

答案 1 :(得分:2)

ffrom方法的本地方法,所以它都是对它的引用。 你想要的是:

pub struct UserAction<'u> {
    _act: &'u mut (FnMut() + 'u)
}

impl<'u, F: FnMut() + 'u> From<&'u mut F> for UserAction<'u> {
//                             ^^^^^^^
    fn from(f: &'u mut F) -> Self {
//             ^^^^^^^
        UserAction { _act: f as &'u mut (FnMut() + 'u) }
    }
}