You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust Wasm中如何修改数据?遭遇借用检查器错误

问题分析

错误核心是生命周期逃逸:spawn_local要求传入的Future必须满足'static生命周期,但你在boot方法里把仅在方法体内有效的&mut Self包裹进Rc<RefCell>,这个引用的生命周期无法覆盖异步任务的执行周期,导致编译器报错。

解决方案

别用Rc<RefCell<&mut MyClass>>这种嵌套临时引用的结构,直接把MyClass实例本身放在Rc<RefCell>里管理。这样异步函数持有的是实例的Rc克隆,天然满足'static要求。

修改后的代码:

use std::cell::RefCell;
use std::rc::Rc;

use wasm_bindgen_futures::spawn_local;

use wasm_bindgen::prelude::*;

pub struct MyClass {
    value: u32,
}

impl MyClass {
    pub fn new() -> Rc<RefCell<Self>> {
        Rc::new(RefCell::new(Self { value: 0 }))
    }

    pub async fn boot_async(this: Rc<RefCell<Self>>) {
        this.borrow_mut().value += 1;
    }

    pub fn boot(this: Rc<RefCell<Self>>) {
        let async_function = MyClass::boot_async(this.clone());
        spawn_local(async_function);
    }
}

#[wasm_bindgen(start)]
fn start() {
    let test = MyClass::new();
    MyClass::boot(test);
}
关键修改点
  • 构造函数直接返回Rc<RefCell>:从创建实例开始就用Rc管理,彻底避免临时引用的生命周期问题。
  • boot方法接收Rc<RefCell>:不再依赖&mut Self参数,直接持有实例的Rc克隆,确保异步任务能长期持有有效引用。
  • 移除错误的临时引用包裹:原来的Rc::new(RefCell::new(self))是问题根源,现在直接传递实例的Rc克隆给异步函数。
关于非Wasm环境的"正常"表现

不同异步runtime对Future的生命周期要求不一样:非Wasm环境的spawn可能允许非'static的Future(比如在当前线程栈上快速执行),但这本质是不安全的。Wasm场景下因为依赖JS事件循环,异步任务可能在任意时间点执行,编译器会严格强制'static要求,确保引用始终有效。

内容的提问来源于stack exchange,提问作者Yaroslava Laurie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 04:45:15