簡體   English   中英

如何創建捕獲 Rc 的 wasm_bindgen 閉包<RefCell<_> &gt; 不搬出去?

[英]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 || { .

如何創建 Rc <refcell< to something that already exists?< div><div id="text_translate"><p> 因此,為了自學一些 Rust,我決定創建一個我喜歡的簡單混合數據類型 ChainVec。 這是一個向量的雙向鏈接列表,如果您需要調整可能增長到巨大規模的向量的大小,這很有用。 它使用鏈表邏輯,但查找、搜索和迭代特性要快得多,因為它們的增長時間為 O(n/alot)。 不過,這並不是重點:我遇到的問題會出現在任何雙向鏈表中。</p><p> 這就是問題所在......在 C 中,當我創建新的鏈表節點時,我可以將其“尾部”設置為指向前一個節點的指針。 我可以在 C 中像糖果一樣扔指針,但在 Rust 中,我還不知道如何創建新指針。 這是我嘗試過的...(在 fn push_head 下查找無效行)</p><p> 注意:在我的實現中,chainvec 的“頭”節點是您選擇指向的任何一個,因此列表頭/尾沒有單獨的結構。</p><pre> #[allow(non_snake_case)] use std::{cell::RefCell, rc::Rc}; #[allow(dead_code)] struct ChainVec&lt;T&gt; { item: Option&lt;Vec&lt;T&gt;&gt;, head: Option&lt;Rc&lt;RefCell&lt;ChainVec&lt;T&gt;&gt;&gt;&gt;, tail: Option&lt;Rc&lt;RefCell&lt;ChainVec&lt;T&gt;&gt;&gt;&gt;, } impl&lt;T&gt; ChainVec&lt;T&gt; { fn new(prealloc: usize) -&gt; Self { let vector: Vec&lt;T&gt; = Vec::with_capacity(prealloc); Self { item: Some(vector), head: None, tail: None, } } fn new_with_links(prealloc: usize, head: Option&lt;Rc&lt;RefCell&lt;ChainVec&lt;T&gt;&gt;&gt;&gt;, tail: Option&lt;Rc&lt;RefCell&lt;ChainVec&lt;T&gt;&gt;&gt;&gt;) -&gt; Self { let vector: Vec&lt;T&gt; = Vec::with_capacity(prealloc); Self { item: Some(vector), head: head, tail: tail, } } fn push_head(&amp;mut self, prealloc: usize) { self.head = Some(Rc::new(RefCell::new(ChainVec::new_with_links(prealloc, None, Some(Rc::new(RefCell::new(self))))))); } } #[allow(unused_variables)] fn main() { let alef: ChainVec&lt;u32&gt; = ChainVec::new(100); println,("Hello; world!"); }</pre><p> 顯然,當我嘗試通過 Some(Rc::new(RefCell::new(self))) 在 push_head 中創建一個新指針時,我迷路了。 我有</p><pre>mismatched types expected struct `ChainVec&lt;T&gt;` found mutable reference `&amp;mut ChainVec&lt;T&gt;`</pre><p> 取消引用運算符在這里不做任何事情......我不知道如何繼續。</p><p> 如何創建對已經存在的結構的 Rc&lt;RefCell&lt; 引用? </p></div></refcell<>

[英]How can I create an Rc<RefCell< to something that already exists?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

相關問題 如何使用wasm_bindgen返回帶有JsValue的結果? 如何使用 Rust 和 wasm-bindgen 創建一個閉包,該閉包使用 state 創建另一個閉包? 如何使用帶有類型別名的#[wasm_bindgen]? 如何在 Rust 中的 wasm_bindgen function 中發出 HTTP 請求? 如何創建 Rc <refcell< to something that already exists?< div><div id="text_translate"><p> 因此,為了自學一些 Rust,我決定創建一個我喜歡的簡單混合數據類型 ChainVec。 這是一個向量的雙向鏈接列表,如果您需要調整可能增長到巨大規模的向量的大小,這很有用。 它使用鏈表邏輯,但查找、搜索和迭代特性要快得多,因為它們的增長時間為 O(n/alot)。 不過,這並不是重點:我遇到的問題會出現在任何雙向鏈表中。</p><p> 這就是問題所在......在 C 中,當我創建新的鏈表節點時,我可以將其“尾部”設置為指向前一個節點的指針。 我可以在 C 中像糖果一樣扔指針,但在 Rust 中,我還不知道如何創建新指針。 這是我嘗試過的...(在 fn push_head 下查找無效行)</p><p> 注意:在我的實現中,chainvec 的“頭”節點是您選擇指向的任何一個,因此列表頭/尾沒有單獨的結構。</p><pre> #[allow(non_snake_case)] use std::{cell::RefCell, rc::Rc}; #[allow(dead_code)] struct ChainVec&lt;T&gt; { item: Option&lt;Vec&lt;T&gt;&gt;, head: Option&lt;Rc&lt;RefCell&lt;ChainVec&lt;T&gt;&gt;&gt;&gt;, tail: Option&lt;Rc&lt;RefCell&lt;ChainVec&lt;T&gt;&gt;&gt;&gt;, } impl&lt;T&gt; ChainVec&lt;T&gt; { fn new(prealloc: usize) -&gt; Self { let vector: Vec&lt;T&gt; = Vec::with_capacity(prealloc); Self { item: Some(vector), head: None, tail: None, } } fn new_with_links(prealloc: usize, head: Option&lt;Rc&lt;RefCell&lt;ChainVec&lt;T&gt;&gt;&gt;&gt;, tail: Option&lt;Rc&lt;RefCell&lt;ChainVec&lt;T&gt;&gt;&gt;&gt;) -&gt; Self { let vector: Vec&lt;T&gt; = Vec::with_capacity(prealloc); Self { item: Some(vector), head: head, tail: tail, } } fn push_head(&amp;mut self, prealloc: usize) { self.head = Some(Rc::new(RefCell::new(ChainVec::new_with_links(prealloc, None, Some(Rc::new(RefCell::new(self))))))); } } #[allow(unused_variables)] fn main() { let alef: ChainVec&lt;u32&gt; = ChainVec::new(100); println,("Hello; world!"); }</pre><p> 顯然,當我嘗試通過 Some(Rc::new(RefCell::new(self))) 在 push_head 中創建一個新指針時,我迷路了。 我有</p><pre>mismatched types expected struct `ChainVec&lt;T&gt;` found mutable reference `&amp;mut ChainVec&lt;T&gt;`</pre><p> 取消引用運算符在這里不做任何事情......我不知道如何繼續。</p><p> 如何創建對已經存在的結構的 Rc&lt;RefCell&lt; 引用? </p></div></refcell<> 使用wasm_bindgen公開香草Rust類 如何修改RC <RefCell> 從內部關閉? 如何使用 Vec<t> 作為返回類型並使用 wasm_bindgen 使其在 Javascript 中可讀</t> 如何使用 wasm-bindgen 調用作為模塊的 JavaScript 函數? fn(SomeStruct)未實現FromWasmAbi,而SomeStruct是#[wasm_bindgen]
 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM