如何在不拥有它的情况下更改异步块中的变量值

How can I change a variables value from an async block without taking ownership of it

我对 Rust 很陌生,正在尝试使用 Rust 和 wasm-bindgen 制作一个带有 Web Assembly 的小游戏。 我有一个事件侦听器,用于侦听按键和 returns 通过流的方向。 然后我想根据方向变量的值每 500 毫秒向 canvas 元素绘制一些东西。

我的问题是我无法改变异步块中的 direction 变量, 并在 Interval 闭包中使用它。

在异步块和 Interval 闭包中使用 move 关键字使代码编译, 但是方向在区间函数内永远不会改变。 我认为方向变量随后被复制到 block/closure,因为 Direction 枚举实现了 Copy 特征。

我已经包含了我的入口点函数的简化版本:

#[wasm_bindgen]
pub fn run() -> Result<(), JsValue> {
    let mut direction = Direction::Right;

    let fut = async {
        let mut on_key_down = EventListenerStruct::new();

        while let Some(dir) = on_key_down.next().await {
            direction = dir;
          // ^^^^^^^^ this errors because direction does not live long enough
          // argument requires that `direction` is borrowed for `static`
        }
    };
    spawn_local(fut);

    Interval::new(500, || {
        // I want to use direction here
    })
    .forget();

    Ok(())
}

我的问题是;我可以可变地将变量借用到异步块中吗? 我可以在不拥有它的情况下让它活得足够长吗?

提前致谢,

是的,您可以使用 Arc 和 Mutex 来做到这一点。

use std::sync::{Arc, Mutex};

fn main() {
    let mut direction = Arc::new(Mutex::new(Direction::Right));

    let direction2 = Arc::clone(&direction);
    let fut = async {
        let mut on_key_down = EventListenerStruct::new();

        while let Some(dir) = on_key_down.next().await {
            *direction2.lock().unwrap() = dir;
        }
    };
    spawn_local(fut);

    Interval::new(500, || {
        let direction = direction.lock().unwrap();
    })
    .forget();
}