当我将值移动到已生成的Tokio任务中时,Rust寿命为何如此重要?

问题描述

我正在尝试创建一个结构来管理一个Tokio任务,其中一个if(regularPrice >= discountPrice){ TextSpan( text: ' $regularPrice',style: TextStyle( decoration: Textdecoration.lineThrough,decorationThickness: 2.85,fontSize: 15,ontWeight: FontWeight.bold),),TextSpan( text: ' $discountPrice',style: TextStyle( fontSize: 15,}else{ TextSpan( text: ' $regularPrice',} 用来向任务发送输入,一个const categories = [{ "category": "Category 1","desc": "Description 1 of the category 1" },{ "category": "Category 1","desc": "Description 2 of the category 1" },{ "category": "Category 2","desc": "Description 1 of the category 2" },"desc": "Description 2 of the category 2" },{ "category": "Category 3","desc": "Description 1 of the category 3" },"desc": "Description 2 of the category 3" } ]; const newArr = categories.reduce((acc,curr) => { let target = acc.find(element => element.category === curr.category); if (target) { if (!target.descriptionList.includes(curr)) { delete curr.category; target.descriptionList.push(curr); } } else { acc.push({ category: curr.category,descriptionList: [{ desc: curr.desc }] }) } return acc },[]); console.log('newArr: ' + JSON.stringify(newArr)); 用来接收来自任务的输出,还有一个我可以处理的句柄最后加入。

newArr: [
  {
    "category": "Category 1","descriptionList": [
      {
        "desc": "Description 1 of the category 1"
      },{
        "desc": "Description 2 of the category 1"
      }
    ]
  },"descriptionList": [
      {
        "desc": "Description 1 of the category 2"
      },{
        "desc": "Description 2 of the category 2"
      }
    ]
  },"descriptionList": [
      {
        "desc": "Description 1 of the category 3"
      },{
        "desc": "Description 2 of the category 3"
      }
    ]
  }
]

当我尝试对此进行编译时,对于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保留在调用范围内。有谁知道在这种情况下如何满足编译器的要求?

解决方法

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

B: 'static意味着B的所有生存期参数都超过'staticref)。例如,拥有自己的数据并因此没有生存期参数(例如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 {