rust學習八、包和模組

正在战斗中發表於2024-11-13

總體上,也沒有什麼特別的地方,和其它語言比較起來。

我們可以看懂熟悉的字眼:包括、模組、use、公共等等

如果是英文,則需要知道crate、pub。

本章節對應相關書籍的第七章節.

一、一個rust可執行程式的大體結構

就本章節而言,尚未接觸到一個非常複雜的工程結構,據說有什麼工作空間。

不考慮工作空間,那麼一個rust可執行應用大概如下:

所謂的單元包即"crate"。

crate - 木箱、一箱 等含義。為了方便我們翻譯為單元包,小包。

這是因為package已經約定成俗翻譯為"包“,那麼crate作為一個程式容器,翻譯為”小包、單元包"也是可以的。

如果要這個程式可以執行,則至少應該包含一個二進位制可執行包,即src/main.rs,其中應該有main()入口。

而這個package反而有點類似於maven工程,cargo new 就是建立一個 package(工程):

如果你熟悉java程式設計,那麼rust的package,crate大體可以等價於:

rust java

---------------------------------------------

package- project

crate package

單元包分類

強調幾點:

  1. 外部單元包一般透過cargo install 安裝到Cargo.toml中
  2. 庫單元位於src/lib.rs中。可以使用 cargo new --lib xxx 來建立一個庫單元包,而不是一個包含了二進位制單元包的可執行程式

下圖包含了兩個示例:lzfmatch(庫單元包), school(一個可執行程式,包含了一個二進位制單元)

單元包組成

圖看起來好像複雜,例子反而簡單。

二、模組系統

換一個角度,一個應用程式,就是無數模組構成的.

和其它大部分語言一樣:可以模組巢狀模組;模組巢狀的層次沒有明說(應該也不會有那麼瘋狂自找麻煩的)

圖_單元包和模組的簡單關係示意

實際可以巢狀很多層次。

三、示例

如果看不太明白,或者不太想看,那麼直接看例子最直接的。

3.1、結構

包含了兩個二級模組student,teacher,以及5個三級子模組。

作業系統檔案結構

從上圖可以看出:

模組student的子包位於同名子目錄下student/stuent_course.rs,student/student_info.rs

模組teacher的子包是內聯的(即和teacher自身同個檔案)

/**
 * 子模組1-通用
 */
pub mod teacher_common {
    pub fn teach() {
        println!("老師在上課");
        super::teacher_inner::learn();   //即使和被訪問物件位於同個父親下兩個子模組下,兩個子模組內的方法也只能訪問對方公共的成員
        //super::teacher_inner::laugh(); //企圖訪問私有成員會編譯錯誤的。
    }
}

/**
 * 子模組2-家庭
 */
pub mod teacher_family {}

/**
 * 內部模組-私有
 */
mod teacher_inner {
    /**
     * 即使處於同個層級,如果不定義為pub,其它同層級的方法也無法訪問,因為畢竟屬於不同模組
     */
    pub fn learn() {}
    fn laugh(){
        println!("老師在笑");
    }
}

pub fn go() {
    println!("教師模組");
}

3.2、 引入/引用說明

//use crate::student::student_info::stru_student;   //通常不要那麼麻煩,還要加crate
use student::student_info::stru_student;  //引入單個
use student::student_info::*;  //引入所有的,不要那麼麻煩
use student::student_course::Course as Subject;  //引入單個且用別名

mod teacher;
mod student;


fn main() {
    teacher::go();    
    student::go();

    //直接使用子模組的子模組方法
    teacher::teacher_common::teach();
    let stu=stru_student{
        name:"tom".to_string(),
        sex:"".to_string(),
        age:12,
    };

    print_student(stu);

    let sub=Subject::漢語;
    print!("{:?}",sub);
}

上文演示了3種常用的use語法。

注意:由於這些模組都是位於本單元包內,所以需要先用 mod xxx的語法引入模組,然後再使用use語句引入模組內物件(型別、方法等)

3.3、pub use

rust還有一個比較獨特的pub use,原文的意思是(re-exporting),意思是如果被的作用域匯入當前模組,那麼可以訪問這裡pub use的物件。

我們來做個例子:

1.為teacher模組新增子模組study,study下有函式study_hard

2.在teacher中pub use study::study_hard

3.在main.rs種使用

四、小結

  1. 雖然粗看起來,rust的程式組織有點小複雜,但是和大部分語言沒有什麼區別,和java很像
  2. rust透過包、單元包(二進位制、庫)、模組來組織應用中的程式碼
  3. 一個單元包可以包含許多模組
  4. 模組可以包含子模組
  5. 模組之間的巢狀層次沒有明確的限定,但不會有人巢狀太多層次
  6. rust利用pub use可以做到重匯出作用

相關文章