为什么 Rust 强制执行“静态生存期”,即使我已经指定了一个?我可以覆盖它吗?

Why Rust enforces 'static lifetime even I have specified one? Can I override it?

提问人:Ruxo 提问时间:1/15/2023 更新时间:1/15/2023 访问量:101

问:

谁能建议我做错了什么。我正在编写一个用于间接调用闭包的结构,此代码将与 C 库一起使用。Callback

我试图显式声明一个类的生存期,但 Rust 强制我使用生存期,我知道它不是静态的。我的代码如下所示:Callback'static

use std::ffi::c_void;
use std::marker::PhantomData;

struct Callback<'h> {
    f: Box<dyn FnMut()>,
    r: *const c_void,
    _lifetime: PhantomData<&'h ()>
}

impl<'h> Callback<'h> {
    fn new<F>(handler: F) -> Self where F: FnMut() + Send + 'h {
        let f = Box::new(handler);
        let r = f.as_ref() as *const dyn FnMut() as *const c_void;
        Callback::<'h> { f, r, _lifetime: PhantomData }
    }
}

编译器错误如下:

error[E0310]: the parameter type `F` may not live long enough
  --> src\main.rs:14:26
   |
14 |         Callback::<'h> { f, r, _lifetime: PhantomData }
   |                          ^ ...so that the type `F` will meet its required lifetime bounds
   |
help: consider adding an explicit lifetime bound...
   |
11 |     fn new<F>(handler: F) -> Self where F: FnMut() + Send + 'h + 'static {
   |                                                                +++++++++

如果我使用建议的生存期,那么闭包必须是静态的,这不是我的本意。'static

如何迫使 Rust 信任我的一生?有什么解决方法吗?或者,有没有其他方法可以实现相同的目标?

Rust 回调 闭包生存期

评论


答:

2赞 kmdreko 1/15/2023 #1

存储在结构字段中将对 trait 对象具有默认约束。你可以通过用以下方式注释它来放松它:Box<dyn Trait>'static'h

struct Callback<'h> {
    f: Box<dyn FnMut() + 'h>, // <------------
    r: *const c_void,
    _lifetime: PhantomData<&'h ()>
}

有了这个变化,你可能不再需要_lifetime了。

评论

0赞 Ruxo 1/15/2023
谢谢。我没有意识到泛型类型也需要时间线!这非常有效!
0赞 user3070377 1/15/2023
你能澄清一下吗?如果结构体中没有引用,它如何具有生存期?
1赞 kmdreko 1/15/2023
@user3070377特征对象可以表示任何类型,这意味着它们可以表示具有引用的结构。上面的语法用于表示 trait 对象只要存在 就允许有引用。'h