網站首頁 編程語言 正文
前言
本文適用于剛開始學習rust的同學,用于幫助理解rust模塊間是如何相互引用的。本文盡量用極少的代碼來演示,即便之前沒有了解過rust也可以混個眼熟。用的時候可以有個印象。
如果你之前沒有了解過rust,只需要知道:Cargo-依賴管理工具,類似于npm,Cargo 使用文件放置約定,即文件名就是模塊名。crate-集裝箱,是一組功能的封裝,類似于npm包。
本文探討的場景是在項目中對代碼進行不同程度的文件拆分和模塊抽離時,往往需要在一個文件中引入另一個模塊的部分代碼,在javascript中,我們可以通過導入導出來使用其他模塊的代碼,這個過程我們只需要關心導入路徑是否正確。
export const name= xx import lodash from './lodash'
而在rust中,模塊不再通過文件路徑的方式引入,而是通過cargo以及約定的模塊聲明方式來構建模塊樹,然后通過use關鍵字來使用。但是rust的文檔在文件拆分和模塊使用上做的示例不太詳細,于是就參考一些發布的crate的組織方式進行了梳理。
模塊聲明&使用
假如我們想實現一個加法模塊,并提供給其他地方使用。我們可以有如下三種組織方式
Cargo 使用文件放置約定,因此模塊查找以src目錄下的rs文件或者目錄為準,并且只會查找一級,嵌套文件夾下的rs文件不可以直接被其他文件使用。
方法一:直接在根文件下聲明 add.rs
我們可以通過在src下添加模塊名同名的文件,cargo就可以識別到add模塊。
├── Cargo.lock ├── Cargo.toml ├── src │ ├── add.rs │ ├── lib.rs
方法二:聲明add文件夾,文件夾下包含 mod.rs
如果模塊是文件夾,則必須有mod.rs文件。這類似于javascript的index.js。cargo仍然可以識別到這是add模塊
├── Cargo.lock ├── Cargo.toml ├── src │ ├── add │ │ ├── mod.rs │ ├── lib.rs
假設我們的代碼內容如下,并位于文件add.rs 或者add/mod.rs內
pub fn add_fn(a: i32, b: i32) -> i32 { a + b }
那么在lib.rs中我們可以通過如下方式調用我們的add模塊
// 聲明模塊并引用模塊內的函數 mod add; pub use crate::add::add_fn; pub fn test_lib() { add_fn(1,2); }
方法三:add.rs和add文件夾同時存在
這種方式的目錄結構看起來像下面這樣
├── Cargo.lock ├── Cargo.toml ├── src │ ├── add │ │ └── add_m.rs │ ├── add.rs // index.js │ ├── lib.rs
add.rs負責入口模塊的導入導出,add文件夾下則存放其余相關聯的其他模塊。這類似于javascript的index.js統一導出了多個其他模塊。和上面不同的是這里 導入使用到了mod關鍵字來拆分模塊;
文件內容看起來像下面這樣
add.rs
pub mod add_m; // 類似于 export * from './validate; export * from './helper'
add/add_m.rs
pub fn add_fn(a: i32, b: i32) -> i32 { a + b }
lib.rs
mod add; pub use crate::add::add_m::add_fn; pub fn test_lib() { add_fn(1,2); }
上述三種方式使用較多的應該是前兩種,并且在大型項目內第二種更為合理,可以更好的組織文件。那么當一個模塊文件夾下拆分多個模塊文件時該怎調用相鄰文件呢?
同模塊相鄰文件引用
我們調整目錄結構如下
├── Cargo.lock ├── Cargo.toml ├── src │ ├── add │ │ ├── mod.rs │ │ ├── print.rs │ │ └── user.rs // user會調用print的方法 │ ├── lib.rs
在add模塊下多了print和user。user會調用print的方法。
print.rs
pub mod my_print { pub fn print_hello() { println!( hello ) } } // 這里的pub mod 可以簡單理解為ts的declare module ,里面是module的可用屬性 // declare module my_print { // export function print_hello(): string; // }
user.rs
use super::print::my_print; pub fn hello_user() { my_print::print_hello(); } pub struct User { pub name: String, }
同模塊下的文件互相引用使用super關鍵字。
mod.rs
// mod.rs為入口文件, 下面用mod聲明會先去同文件夾下查找同名文件,如果沒有則看是否有滿足條件 的同名文件夾 // 例如 add 文件夾下沒有print.rs 則查找是否有print文件夾并且文件夾下有mod.rs。 mod print; mod user; // 因為是同一個模塊文件夾下,并且在入口文件使用,所以這里應self pub use self::user::hello_user; pub use self::user::User; pub mod add_fn { // use super::*; 如果有這行,則下面不用每次調用super pub fn add(a: i32, b: i32) -> i32 { // 注意這里super關鍵字,因為hello_user是在另一個模塊聲明的,模塊間不能直接調用所以需要使用super來從模塊根進行查找調用 super::hello_user(); let value = super::User { name: String::from( Rust ), }; println!( user name {} , value.name); a + b } } pub fn test_out_ref() { // 這里不在需要super因為不在mod內定義 hello_user(); }
不同模塊引用
我們新增一個模塊multip,返回兩個數相乘的結果,目錄結構如下
├── Cargo.lock ├── Cargo.toml ├── src │ ├── add │ │ ├── mod.rs │ │ ├── print.rs │ │ └── user.rs // user會調用print的方法 │ ├── multip // ------- 新增這個模塊 │ │ ├── mod.rs法 │ ├── lib.rs
multip/mod.rs
pub fn res_multip(a: i32, b: i32) -> i32 { a * b }
假設add文件引入multip
mod print; mod user; pub use self::user::hello_user; pub use self::user::User; // 新增下面這行 use crate::multi::multip;
如此便可以使用另一個模塊的內容了。當然其他模塊的相互引用方式一致。
小結
rust的模塊使用方式總體來說是比較簡單的,由于官方文檔在模塊拆分和組織上并沒有進行較完善的說明,所以對于剛從js轉到rust學習的同學可能會有一點不適應。通過前面內容已經較為清晰的梳理了下使用方式。希望可以對需要的同學有所幫助。
原文鏈接:https://juejin.cn/post/7070481262749679653
相關推薦
- 2022-11-18 Redis?存儲對象信息用?Hash?和String的區別_Redis
- 2022-10-23 使用React組件編寫溫度顯示器_React
- 2022-06-23 nginx日志格式分析以及修改詳解_nginx
- 2022-10-01 Python類與實例的使用詳解_python
- 2022-10-28 UpdateLayeredWindow實現任意異形窗口使用詳解_C#教程
- 2023-01-02 Android?數據結構全面總結分析_Android
- 2022-10-14 el-tree 懶加載,默認加載N級.異步加載子節點
- 2022-08-28 Python代碼中引用已經寫好的模塊、方法的兩種方式_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支