src/lib.rs
lib.rs
是模板的主要源文件。名称 lib.rs
通常意味着此 Rust 项目将被编译为库。
它包含三个关键部分
我们将从 lib.rs
中最重要的部分开始 - 两个 #[wasm_bindgen]
函数(您可以在文件底部找到它们)。在许多情况下,这是您需要修改的 lib.rs
的唯一部分。
1. 使用 wasm_bindgen
为了更方便地从 wasm-bindgen
箱子中公开功能,我们可以使用 use
关键字。use
允许我们方便地引用箱子或模块的各个部分。您可以在 本书的这一章 中了解更多关于 Rust 如何让您编写模块化代码的信息。
#![allow(unused)] fn main() { use wasm_bindgen::prelude::*; }
许多箱子包含一个前导,这是一个方便一次导入所有内容的列表。这允许模块的常见功能在没有冗长的前缀的情况下方便地访问。例如,在这个文件中,我们之所以能够使用 #[wasm_bindgen]
,是因为它被前导引入作用域。
此 use
末尾的星号表示 wasm_bindgen::prelude
模块(即 wasm_bindgen
箱子内的 prelude
模块)中的所有内容都可以被引用,而无需在前面加上 wasm_bindgen::prelude
。
例如,#[wasm_bindgen]
也可以写成 #[wasm_bindgen::prelude::wasm_bindgen]
,虽然不推荐这样做。
1. #[wasm_bindgen]
函数
#[wasm_bindgen]
属性表示它下面的函数将在 JavaScript 和 Rust 中都可访问。
#![allow(unused)] fn main() { #[wasm_bindgen] extern { fn alert(s: &str); } }
extern
块将外部 JavaScript 函数 alert
导入到 Rust 中。此声明是必须的,以便从 Rust 中调用 alert
。通过以这种方式声明它,wasm-bindgen
将为 alert
创建 JavaScript 存根,允许我们在 Rust 和 JavaScript 之间传递字符串。
我们可以看到 alert
函数需要一个类型为 &str
的单个参数 s
,即字符串。在 Rust 中,任何字符串文字,例如 "Hello, test-wasm!"
,都是 &str
类型。因此,alert
可以通过编写 alert("Hello, test-wasm!");
来调用。
我们知道以这种方式声明 alert
,因为这是我们在 JavaScript 中调用 alert
的方式 - 通过向它传递一个字符串参数。
#![allow(unused)] fn main() { #[wasm_bindgen] pub fn greet() { alert("Hello, test-wasm!"); } }
如果我们在没有 #[wasm_bindgen]
属性的情况下编写 greet
函数,那么 greet
将无法在 JavaScript 中轻松访问。此外,我们将无法在 JavaScript 和 Rust 之间本机转换某些类型,例如 &str
。因此,#[wasm_bindgen]
属性和之前对 alert
的导入都允许从 JavaScript 中调用 greet
。
这就是您需要了解的与 JavaScript 交互的所有内容,至少是入门!您可以通过阅读 wasm-bindgen
文档 来了解更多信息!
如果您对其他内容感到好奇,请继续阅读。
2. 箱子组织
#![allow(unused)] fn main() { mod utils; }
此语句声明了一个名为 utils
的新模块,该模块由 utils.rs
的内容定义。等效地,我们可以将 utils.rs
的内容放在 utils
声明中,用以下内容替换该行
#![allow(unused)] fn main() { mod utils { // contents of utils.rs } }
无论哪种方式,utils.rs
的内容都定义了一个名为 set_panic_hook
的公共函数。因为我们将其放在 utils
模块中,所以我们可以通过编写 utils::set_panic_hook()
来直接调用该函数。我们将在 src/utils.rs
中讨论如何以及为什么使用此函数。
#![allow(unused)] fn main() { // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global // allocator. if #[cfg(feature = "wee_alloc")] { #[global_allocator] static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; }
在编译时,这将测试此编译是否启用了 wee_alloc
功能。如果启用了它,我们将根据 wee_alloc
的文档 配置一个全局分配器,否则它将编译成空内容。
正如我们之前所见,[features]
中的 default
向量只包含 "console_error_panic_hook"
,而不包含 "wee_alloc"
。因此,在这种情况下,此块将被替换为空代码,因此将使用默认内存分配器而不是 wee_alloc
。