闭包
该#[wasm_bindgen]
属性支持将一些 Rust闭包 传递给JS. 你可以做的例子是:
# #![allow(unused_variables)] #fn main() { #[wasm_bindgen] extern { fn foo(a: &Fn()); // could also be `&mut FnMut()` } #}
这是一个 从 JS 导入foo
函数,其中第一个参数是 a
: 堆栈闭包. 您可以调用此函数带有参数a
:&Fn()
在正常的 html 与 JS 中获得这个函数. 然而,当·foo
函数使用时,JS函数将失效,并且使用它将引发异常.
另外, 闭包还支持 参数 和 返回值 的导出,例如:
# #![allow(unused_variables)] #fn main() { #[wasm_bindgen] extern { type Foo; fn bar(a: &Fn(u32, String) -> Foo); } #}
有时,不希望这些闭包的堆栈行为影响. 例如,您希望在 JS 中通过下一次事件循环中运行setTimeout
的闭包. 为此,您希望导入的函数返回,和 JS闭包 需要有效!
要支持此用例,您可以执行以下操作:
# #![allow(unused_variables)] #fn main() { use wasm_bindgen::prelude::*; #[wasm_bindgen] extern { fn baz(a: &Closure<Fn()>); } #}
该Closure
类型定义在wasm_bindgen
箱子和代表"长寿"的闭包. JS闭包传递给了baz
之后, baz
返回仍然有效,在 Rust 中 JS闭包 的有效性 与 Closure
的生命周期 有关. 一旦Closure
被删除, 它将释放其内部内存, 并使相应的 JS函数 无效.
像堆栈闭包一样Closure
也支持FnMut
:
# #![allow(unused_variables)] #fn main() { use wasm_bindgen::prelude::*; #[wasm_bindgen] extern { fn another(a: &Closure<FnMut() -> u32>); } #}
这时你不能将一个 JS闭包 传递给Rust,在有限的情况下,你只能将一个 Rust闭包 传递给JS.