src/lib.rs
lib.rs
是範本的主要原始碼檔案。名稱 lib.rs
通常意味著這個 Rust 專案將被編譯為函式庫。
它包含三個關鍵部分
我們將從 lib.rs
最重要的部分開始 - 兩個 #[wasm_bindgen]
函式(您可以在檔案底部找到它們)。在許多情況下,這是您唯一需要修改的 lib.rs
部分。
1. 使用 wasm_bindgen
為了更方便地從 wasm-bindgen
crate 公開功能,我們可以使用 use
關鍵字。use
允許我們方便地引用 crate 或模組的部分內容。您可以在本書的這一章中了解更多關於 Rust 如何讓您編寫模組化程式碼的資訊。
#![allow(unused)] fn main() { use wasm_bindgen::prelude::*; }
許多 crate 都包含一個 prelude,一個方便一次匯入所有內容的清單。這允許方便地訪問模組的常用功能,而無需冗長的前綴。例如,在這個檔案中,我們可以使用 #[wasm_bindgen]
僅僅是因為它是由 prelude 引入範圍的。
這個 use
結尾的星號表示 wasm_bindgen::prelude
模組(即 wasm_bindgen
crate 內部的 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("Hello, test-wasm!");
來呼叫 alert
。
我們知道要以這種方式聲明 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. Crate 組織
#![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
。