异步流中的生命周期(生锈)

Life time in async flow (rust)

你能给我解释一下这是什么原因吗

use std::future::Future;

pub struct A{}

pub struct B<'a>{
    pub i: &'a A,
}

impl<'a> B<'a>{
    fn new(x:&'a A)->Self{
        Self{i:x}
    }

    async fn print_any(&self){
        println!("xxxxxxxxxxxxxxxxxxxxx")
    }
}

fn main() {
    let aa = A{};
    let bb = B::new(&aa);

    futures::future::join3(
        tokio::spawn(bb.print_any()),
        tokio::spawn(bb.print_any()),
        tokio::spawn(bb.print_any())
    );
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7556ae4ab612ca6a99e51ec4c736425f

error[E0597]: `aa` does not live long enough
  --> src/main.rs:23:21
   |
23 |     let bb = B::new(&aa);
   |              -------^^^-
   |              |      |
   |              |      borrowed value does not live long enough
   |              argument requires that `aa` is borrowed for `'static`
...
32 | }
   | - `aa` dropped here while still borrowed

以及如何解决这个问题?

线程安全要求线程不能借用小于静态的值。

您可以使用 Arc 将线程安全指针传递给每个线程。

此外,如果您希望能够使用 tokio 运行时,则必须使用 tokio main()

我找不到使用 join3 方法的解决方案,因为表达式无法创建 3 个 Arc 引用,而不必在线程内借用 3 倍相同的值。

所以我提出这个解决方案

use std::sync::Arc;
use std::io;

pub struct A{}

pub struct B {
    pub i: Arc<A>,
}

impl  B {
    fn new(x:Arc::<A>) -> Self {
        Self{i:x}
    }
    
    async fn print_any(&self) {
        println!("xxxxxxxxxxxxxxxxxxxxx")
    }
}

#[tokio::main]
async fn main()-> io::Result<()> {

    let aa = Arc::new(A{});
    let bb = Arc::new(B::new(aa));
    
    for _ in 0..3 {
        let b = Arc::clone(&bb);
        tokio::spawn( async move {
          b.print_any().await  ;
        });
    }

    Ok(())
}

使用 Arc 指针消除了使用显式生命周期参数的必要性。