rust - 当我将值移动到生成的 Tokio 任务中时,为什么 Rust 生命周期很重要?

标签 rust ownership rust-tokio lifetime-scoping

我正在尝试创建一个结构体来管理 Tokio 任务,其中一个 tokio::sync::mpsc::Sender 将输入发送到任务,一个 tokio::接收任务输出的sync::mpsc::Receiver,以及我可以在最后加入的句柄。

use tokio::sync::mpsc;
use tokio::task::JoinHandle;

// A type that implements BlockFunctionality consumes instances of T and
// produces either Ok(Some(U)) if an output is ready, Ok(None) if an output
// is not ready, or an Err(_) if the operation fails
pub trait BlockFunctionality<T, U> {
    fn apply(&mut self, input: T) -> Result<Option<U>, &'static str>;
}

pub struct Block<T, U> {
    pub tx_input: mpsc::Sender<T>,
    pub rx_output: mpsc::Receiver<U>,
    pub handle: JoinHandle<Result<(), &'static str>>,
}

impl<T: Send, U: Send> Block<T, U> {
    pub fn from<B: BlockFunctionality<T, U> + Send>(b: B) -> Self {
        let (tx_input, mut rx_input) = mpsc::channel(10);
        let (mut tx_output, rx_output) = mpsc::channel(10);

        let handle: JoinHandle<Result<(), &'static str>> = tokio::spawn(async move {
            let mut owned_b = b;

            while let Some(t) = rx_input.recv().await {
                match owned_b.apply(t)? {
                    Some(u) => tx_output
                        .send(u)
                        .await
                        .map_err(|_| "Unable to send output")?,
                    None => (),
                }
            }

            Ok(())
        });

        Block {
            tx_input,
            rx_output,
            handle,
        }
    }
}

当我尝试编译此错误时,B 出现此错误,其他两个类型参数也出现类似错误:

   |
22 |     pub fn from<B: BlockFunctionality<T, U> + Send>(b:B) -> Self {
   |                 -- help: consider adding an explicit lifetime bound...: `B: 'static +`
...
27 |         let handle:JoinHandle<Result<(), &'static str>> = tokio::spawn(async move {
   |                                                           ^^^^^^^^^^^^ ...so that the type `impl std::future::Future` will meet its required lifetime bounds

我很难理解生命周期的问题出在哪里。按照我的理解,生命周期问题通常来自于生命周期不够长的引用,但我正在移动值,而不是使用引用。我将 brx_inputtx_output 移动到闭包中,并保留 tx_inputrx_output code> 和调用范围中的 handle。有谁知道在这种情况下如何满足编译器的要求?

最佳答案

这些可能是引用或包含引用。引用类型是有效类型:B可能是&'a str 。或B可能是SomeType<'a> ,一种带有生命周期参数的类型,它本身包含 &'a str .

也就是说B: 'static意味着 B 的所有生命周期参数活下去'static (ref)。例如,拥有自己的数据并因此没有生命周期参数的类型(例如 String )满足此界限。但是&'static str也满足界限。

因为tokio::spawn创建一些其生命周期不是静态范围的东西,它 requires a 'static argument .

因此,为了满足编译器的要求,请添加 'static边界:

impl<T: 'static + Send, U: 'static + Send> Block<T, U> {
    pub fn from<B: 'static + BlockFunctionality<T, U> + Send>(b:B) -> Self {

关于rust - 当我将值移动到生成的 Tokio 任务中时,为什么 Rust 生命周期很重要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64528913/

相关文章:

asynchronous - 从 UdpSocket 异步读取

generics - 指定泛型参数属于一小组类型

rust - 可变借用到 Mutex 内部的对象 - 如何重构?

copy - 按值重载运算符会导致使用移动的值

rust - 如何从 FuturesUnordered 返回错误?

multithreading - 是否可以在当前线程中在 Tokio 的当前线程上生成工作?

rust - 如何指定生命周期以使本地引用值与传入引用不同?

Rust 中的套接字

rust - 我的变量的生命周期是否由于添加了明显不相关的指令而发生变化?

Ubuntu 14.04 : no sftp-access because of bad ownership or modes