简体   繁体   中英

Rust lifetimes with async/await

The following code works without an async keyword on the function. After changing it to async what should I do to make it work.

use cgmath::Vector2;
use winit::window::Window;

struct A<'a> {
    a: Option<&'a Vector2<f32>>,
}

impl A<'_> {
    async fn new(b: &Window) -> A<'_> {
        Self {
            a: None
        }
    }
}

Compile errors

error: lifetime may not live long enough
 --> src/lib.rs:7:9
9  |       async fn new(b: &Window) -> A<'_> {
   |                       -           ----- return type `impl std::future::Future<Output = lang::A<'_>>` contains a lifetime `'1`
   |                       |
   |                       let's call the lifetime of this reference `'2`
10 | /         Self {
11 | |             a: None
12 | |         }
   | |_________^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`

I tried to change it to

struct A<'a> {
    a: Option<&'a Vector2<f32>>,
}

impl<'a> A<'a> {
    async fn new(b: &'a Window) -> A<'a> {
        Self {
            a: None
        }
    }
}

But it borrows the window for too long, and can not move the window after the call. Before I added a lifetime parameter 'a to struct A, it worked.

46 |       let mut a = A::new(&window).await;
   |                          ------- borrow of `window` occurs here
47 |       //player.init();
48 |       event_loop.run(move |event, _, control_flow| {
   |       -              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move out of `window` occurs here
   |  _____|
   | |
49 | |         match event {
50 | |             Event::WindowEvent {
51 | |                 ref event,
52 | |                 window_id,
53 | |             } if window_id == window.id() => if !player.input(event) { // UPDATED!
   | |                               ------ move occurs due to use in closure
...  |
92 | |         }
93 | |     });
   | |______- argument requires that `window` is borrowed for `'static`

When you say Self , you say " A in the impl header". It contains a lifetime. Let's call it 'b :

impl<'b> A<'b> {
    async fn new<'a>(b: &'a Window) -> A<'a> {
        A::<'b> {
            a: None
        }
    }
}

See the mismatch? You were supposed to return A<'a> , but you return A<'b> !

The fix is simple: either use Self for the return type too, or just use A for the return expression:

impl A<'_> {
    async fn new(b: &Window) -> A<'_> {
        A {
            a: None
        }
    }
}

This is the way to go, b: &Window doesn't need the same lifetime as Aa

struct A<'a> {
    a: Option<&'a Vector2<f32>>,
}

impl<'a> A<'a> {
    async fn new(b: &Window) -> A<'a> {
        Self {
            a: None
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM