[英]How can I create a wasm_bindgen Closure which captures a Rc<RefCell<_>> without moving out of it?
我的狀態需要通過 JavaScript 回調多次改變(這是一個游戲,所以來自用戶的輸入需要修改游戲狀態)。 我似乎無法弄清楚該怎么做。 這是我能想到的最簡單的例子,它證明了我遇到的問題:
#[wasm_bindgen(start)]
pub fn run() {
let data = Rc::new(RefCell::new(vec![0]));
let closure = Closure::wrap(Box::new(&mut || {
data.borrow_mut().push(0);
console_log!("{data:?}");
}) as Box<dyn FnMut()>);
closure.forget();
}
我認為使用Rc
會使data
在使用期間保持有效,但我收到此錯誤:
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:19:47
|
19 | let closure = Closure::wrap(Box::new(&mut || {
| _________________________________-_____________^
| |_________________________________|
| ||
20 | || data.borrow_mut().push(0);
21 | || console_log!("{data:?}");
22 | || }) as Box<dyn FnMut()>);
| || ^- - temporary value is freed at the end of this statement
| ||_____||
| |_____|cast requires that borrow lasts for `'static`
| creates a temporary which is freed while still in use
error[E0597]: `data` does not live long enough
--> src/lib.rs:20:9
|
19 | let closure = Closure::wrap(Box::new(&mut || {
| - -- value captured here
| _________________________________|
| |
20 | | data.borrow_mut().push(0);
| | ^^^^ borrowed value does not live long enough
21 | | console_log!("{data:?}");
22 | | }) as Box<dyn FnMut()>);
| |______- cast requires that `data` is borrowed for `'static`
...
25 | }
| - `data` dropped here while still borrowed
我該如何解決這個問題?
Rc
可以讓它足夠活,但目前你正在借用Rc
本身,它在run()
結束時被銷毀。 您需要克隆它,並將克隆移動到閉包中:
#[wasm_bindgen(start)]
pub fn run() {
let data = Rc::new(RefCell::new(vec![0]));
let closure = Closure::wrap(Box::new({
let data = Rc::clone(&data);
&mut move || {
data.borrow_mut().push(0);
console_log!("{data:?}");
}
}) as Box<dyn FnMut()>);
closure.forget();
}
您還不需要借用閉包本身,這就是“借用時臨時值下降”錯誤的原因。 替換&mut move || {
&mut move || {
只需move || {
move || {
.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.