深入講解下Rust模塊使用方式

 更新時間:2022年03月05日 10:42:32   作者:字節教育  
很多時候,我們寫的代碼需要按模塊組織,因為我們無法將大量的代碼都寫在一個文件上,那樣不容易維護,下面這篇文章主要給大家介紹了關于Rust模塊使用方式的相關資料,需要的朋友可以參考下

前言

本文適用于剛開始學習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學習的同學可能會有一點不適應。通過前面內容已經較為清晰的梳理了下使用方式。希望可以對需要的同學有所幫助。

到此這篇關于Rust模塊使用方式的文章就介紹到這了,更多相關Rust模塊使用方式內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 讓開發自動化 用 Eclipse 插件提高代碼質量

    讓開發自動化 用 Eclipse 插件提高代碼質量

    如果能在構建代碼前發現代碼中潛在的問題會怎么樣呢?很有趣的是,Eclipse 插件中就有這樣的工具,比如 JDepend 和 CheckStyle,它們能幫您在軟件問題暴露前發現這些問題。
    2009-05-05
  • 小項目中管理npm包版本的思路與方法

    小項目中管理npm包版本的思路與方法

    這篇文章主要給大家介紹了關于小項目中該如何管理npm包版本的思路與方法,npm包版本管理是非常重要的,文章通過示例代碼介紹的很詳細,需要的朋友可以參考下
    2021-06-06
  • vscode怎么編譯運行

    vscode怎么編譯運行

    本文給大家分享的是vscode怎么一鍵編譯運行的方法,非常的簡單實用,有需要的小伙伴可以參考下
    2020-02-02
  • 如何禁止瀏覽器使用后退按鈕功能

    如何禁止瀏覽器使用后退按鈕功能

    瀏覽器的后退按鈕使得我們能夠方便地返回以前訪問過的頁面,它無疑非常有用。但有時候我們不得不關閉這個功能,以防止用戶打亂預定的頁面訪問次序。
    2014-09-09
  • 如何在網頁中顯示服務器時間

    如何在網頁中顯示服務器時間

    在網頁上顯示時間,如果取的是用戶本機的時間,由于用戶的時間往往不準確,所以顯示的有問題。而服務器時間一般不會誤差太大,所以最好顯示服務器時間
    2013-03-03
  • 算法系列15天速成 第七天 線性表【上】

    算法系列15天速成 第七天 線性表【上】

    人活在社會上不可能孤立,比如跟美女有著千絲萬縷的關系,有的是一對一,有的是一對多,有的是多對多
    2013-11-11
  • Node后端Express框架安裝及應用

    Node后端Express框架安裝及應用

    Express 是一個簡潔而靈活的 node.js Web應用框架, 提供了一系列強大特性幫助你創建各種 Web 應用和豐富的 HTTP 工具,如果你不會jJava or Python等后端,使用 Express可以幫助我們快速地搭建一個完整功能的網站
    2021-08-08
  • vscode如何安裝漢化和Python智能感知

    vscode如何安裝漢化和Python智能感知

    VSCode(VisualStudioCode)是由微軟研發的一款免費、開源的跨平臺文本(代碼)編輯器,算是目前前端開發幾乎完美的軟件開發工具。今天我們來看看它如何使用呢
    2020-01-01
  • 算法系列15天速成 第八天 線性表【下】

    算法系列15天速成 第八天 線性表【下】

    上一篇跟大家聊過“線性表"順序存儲,通過實驗,大家也知道,如果我每次向順序表的頭部插入元素,都會引起痙攣,效率比較低下,第二點我們用順序存儲時,容易受到長度的限制,反之就會造成空間資源的浪費
    2013-11-11
  • Geohash的原理、算法和具體應用探究

    Geohash的原理、算法和具體應用探究

    這篇文章主要介紹了Geohash的原理、算法和具體應用探究,Geohash可以實現當前手機應用中的查找附近的人功能,需要的朋友可以參考下
    2014-07-07

最新評論

免费人成视频在线观看