0

我对 rust 很陌生,尝试使用 rust 和 wasm-bindgen 制作一个带有 web 组件的小游戏。我有一个事件监听器,它监听按键,并通过流返回一个方向。然后我想根据方向变量的值每 500 毫秒向画布元素绘制一些东西。

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

在 async 块和 Interval 闭包中使用move关键字可以编译代码,但是方向在间隔函数内永远不会改变。我认为方向变量然后被复制到块/闭包中,因为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(())
}

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

提前致谢,

4

1 回答 1

1

是的,您可以使用 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();
}
于 2020-04-21T23:07:21.607 回答