我正在try 使用包含VEC的Tokio::Sprown运行一个异步任务.我从编译错误消息中得到的理解是,我没有满足生命周期界限,但我不确定实现这一界限的正确方法是什么.

use tokio::sync::mpsc as tokiompsc;

pub fn _history<T: Clone + Send + Sync>() {
    let (data_tx, mut data_rx) = tokiompsc::channel::<T>(10);
    tokio::spawn(async move {
        let mut destinations: Vec<T> = Vec::new();
        data_rx.recv();
    });
}

编译器错误:

error[E0310]: the parameter type `T` may not live long enough
  --> src\history_generic.rs:18:5
   |
18 | /     tokio::spawn(async move {
19 | |         let mut destinations: Vec<T> = Vec::new();
20 | |         data_rx.recv();
21 | |     });
   | |______^ ...so that the type `T` will meet its required lifetime bounds
   |
help: consider adding an explicit lifetime bound...
   |
16 | pub fn _history<T: Clone + Send + Sync + 'static>() {
   |                                        +++++++++

我已经参考了学习铁 rust 教程,但不知道如何解决这个问题.

推荐答案

如果您查阅tokio::spawn的文档,它需要future 的'static作为参数(在本例中是async move闭包).我认为这意味着T需要具有相同的边界,因为Vec<T>作为闭包的一部分被捕获,并且是Future的状态的一部分.如错误消息所示,避免这种情况的一种方法是将 + 'static添加到T的界限中.

'static表示该类型不受比程序生存期短的任何其他生存期的约束--基本上,如果您有T,则该T不包含对在程序运行时可能消失的任何其他数据的引用.通常,不满足'static界限的类型不能在单独的异步任务之间轻松移动,因为这会限制这些任务的生存期.

关于'static个生命周期界限的更多细节:https://doc.rust-lang.org/rust-by-example/scope/lifetime/static_lifetime.html#trait-bound.正如上面提到的,大多数"普通"拥有的类型都满足这个界限.

Rust相关问答推荐

空字符串转换为Box字符串时是否分配?<>

如何访问Rust存储值的内存地址

如何装箱生命周期相关联的两个对象?

当两者都有效时,为什么Rust编译器建议添加';&;而不是';*';?

有没有办法避免在While循环中多次borrow `*分支`

同时从不同线程调用DLL的不同函数会出现分段错误或产生STATUS_STACK_BUFFER_OVERRUN

Rust 的多态现象.AsRef与Derf

更合理的方法来设计样条线函数器?

在运行特定测试时,如何 suppress cargo test 的空输出?

从管道读取后重置标准输入

可选包装枚举的反序列化

tokio::spawn 有和没有异步块

Rust 如何将链表推到前面?

为什么 Rust 字符串没有短字符串优化 (SSO)?

‘&T as *const T as *mut T’ 在 ‘static mut’ 项目中合适吗?

为什么Rust编译器会忽略模板参数应具有静态生命周期?

枚举的利基优化如何在 Rust 中工作?

如何在 Rust 中将 bson::Bson 转换为 Vec

以 `static` 为前缀的闭包是什么意思?我什么时候使用它?

为什么 &i32 可以与 Rust 中的 &&i32 进行比较?