Rust中箱、包和模塊的學(xué)習(xí)筆記
概述
Rust語言使用模塊系統(tǒng)來組織工程和代碼。模塊系統(tǒng)允許我們將相關(guān)的函數(shù)、類型、常量等組織在一起,形成一個(gè)邏輯上的單元。通過模塊系統(tǒng),我們可以隱藏實(shí)現(xiàn)細(xì)節(jié),只暴露必要的接口,從而提高代碼的可讀性和可維護(hù)性。Rust的模塊系統(tǒng)還支持路徑依賴和重導(dǎo)出等功能,使得代碼的組織更加靈活和方便。
Rust的模塊系統(tǒng)中有三個(gè)非常重要的概念,分別是:箱(Crate)、包(Package)和模塊(Module),下面逐一進(jìn)行介紹。
箱(Crate)
箱,英文為Crate,是Rust中的編譯單元和構(gòu)建單元,也是Cargo打包和分發(fā)的基本單位。Crate可以是庫(library crate),也可以是二進(jìn)制程序(binary crate)。庫crate包含了可以被其他crate使用的代碼,二進(jìn)制crate則包含了可以執(zhí)行的程序。每個(gè)crate都有一個(gè)crate root,它是編譯器開始構(gòu)建crate模塊樹的源文件。對于庫crate,crate root通常是src/lib.rs文件;對于二進(jìn)制crate,crate root通常是src/main.rs文件。
通過crate,我們可以將代碼進(jìn)一步拆分成更小的、更易于管理和維護(hù)的單元。當(dāng)在Cargo中創(chuàng)建一個(gè)新的項(xiàng)目時(shí),實(shí)際上就是在創(chuàng)建一個(gè)Crate。通過cargo new my_crate命令,Cargo將為我們初始化一個(gè)新的Crate結(jié)構(gòu),其中包括:源碼目錄、測試文件、Cargo.toml配置文件等。在Rust中,Crate是編譯時(shí)的概念,它指代的是編譯后生成的一個(gè)單元,可以是一個(gè)庫或者一個(gè)可執(zhí)行程序。
包(Package)
包,英文為Package,是Cargo用于組織和構(gòu)建代碼的基本單位。每個(gè)Rust項(xiàng)目都包含至少一個(gè)Package,并通過名為Cargo.toml的配置文件來描述其屬性和依賴關(guān)系。Package的元數(shù)據(jù)存儲(chǔ)在Cargo.toml文件中,這個(gè)文件包含了關(guān)于Package的基本信息,比如:名稱、版本、作者、描述、許可證等。另外,Cargo.toml還列出了Package的依賴項(xiàng),這些依賴項(xiàng)是其他Packages或Crates,它們會(huì)被Cargo自動(dòng)下載和構(gòu)建。
Package通常包含源碼目錄,包括但不限于src目錄下的main.rs或lib.rs。如果項(xiàng)目更復(fù)雜,還可以有多個(gè)模塊文件和子模塊文件夾。一個(gè)Package可以包含一個(gè)或多個(gè)Crates,但通常情況下,一個(gè)簡單的Package會(huì)對應(yīng)一個(gè)單一的Crate。當(dāng)通過cargo build命令構(gòu)建項(xiàng)目時(shí),最終輸出的二進(jìn)制文件或庫文件就是這個(gè)Crate。
模塊(Module)
模塊,英文為Module,是用于在crate內(nèi)部進(jìn)行分層和封裝的機(jī)制。模塊內(nèi)部又可以包含模塊,從而形成一個(gè)樹形結(jié)構(gòu),也稱為模塊樹。每個(gè)crate會(huì)自動(dòng)產(chǎn)生一個(gè)與當(dāng)前crate同名的模塊,作為這個(gè)樹形結(jié)構(gòu)的根節(jié)點(diǎn)。模塊是元素(比如:函數(shù)、結(jié)構(gòu)體、trait等)的集合,是一種抽象的概念,而文件則是承載這個(gè)概念的實(shí)體。
在Rust中,創(chuàng)建新模塊主要有以下三種方式。
1、在一個(gè)文件中創(chuàng)建內(nèi)嵌模塊。這可以通過直接使用mod關(guān)鍵字來實(shí)現(xiàn),模塊的內(nèi)容會(huì)被包含在大括號內(nèi)部。
2、獨(dú)立的一個(gè)文件就是一個(gè)模塊,文件名即是模塊名。
3、一個(gè)文件夾也可以代表一個(gè)模塊。在這種情況下,有兩種方法可以實(shí)現(xiàn):
(1)文件夾內(nèi)部需要有一個(gè)名為mod.rs的文件,這個(gè)文件就是這個(gè)模塊的入口。在rustc 1.30版本之前,這是唯一的方法。
(2)在文件夾同級目錄里創(chuàng)建一個(gè)與模塊(文件夾)同名的rs文件。在rustc 1.30版本之后,更建議使用這樣的命名方式,以避免項(xiàng)目中存在大量同名的mod.rs文件。
模塊樹
模塊樹是一個(gè)邏輯上的分層結(jié)構(gòu),它反映了源代碼文件的組織方式。每個(gè)Rust項(xiàng)目都可以看作一個(gè)模塊樹的根,其中包含零個(gè)或多個(gè)子模塊。每個(gè)模塊可以進(jìn)一步包含其他的子模塊,從而形成嵌套的層次結(jié)構(gòu)。
在下面的示例模塊樹中,lib.rs是crate的根模塊,shapes和math是它的子模塊。circle和rectangle是shapes的子模塊,algebra和geometry是math的子模塊。shapes之所以是模塊,是因?yàn)閟hapes文件夾下有一個(gè)mod.rs文件。math之所以是模塊,是因?yàn)閙ath同級目錄下有一個(gè)同名的math.rs文件。在后面內(nèi)容的介紹當(dāng)中,我們也會(huì)用到這里的示例模塊樹。
project/ ├── src/ │ ├── lib.rs // crate根模塊 │ ├── shapes/ │ │ ├── mod.rs // shapes模塊 │ │ ├── circle.rs │ │ └── rectangle.rs │ ├── math/ │ │ ├── algebra.rs │ │ └── geometry.rs │ └── math.rs // math模塊
模塊路徑
在Rust中,模塊路徑是用于唯一標(biāo)識(shí)模塊中定義的元素(比如:函數(shù)、結(jié)構(gòu)體等)的字符串。模塊路徑由一系列由雙冒號(::)分隔的標(biāo)識(shí)符組成,從crate根開始,一直到指定的項(xiàng),可以是絕對路徑或相對路徑。
絕對路徑:以crate::開始,表示從crate根開始的完整路徑。在下面的示例代碼中,crate::shapes::circle::Area表示從crate根開始的shapes子模塊、circle子目錄的Area函數(shù)。
use crate::shapes::circle::Area;
相對路徑:直接使用模塊名稱表示同級模塊,或者相對于當(dāng)前模塊的子模塊。有兩個(gè)特殊的標(biāo)識(shí)需要記住,self::表示當(dāng)前模塊,super::表示當(dāng)前模塊的父模塊。
// 在shapes/mod.rs中引用circle.rs中的內(nèi)容 use self::circle::Area; // 在circle.rs中引用shapes/mod.rs中定義的公共常量DEFAULT_RADIUS use super::DEFAULT_RADIUS; // 在同一目錄下引用rectangle模塊 use rectangle::Rectangle;
訪問權(quán)限
在Rust中,訪問權(quán)限是通過pub關(guān)鍵字來控制的。默認(rèn)情況下,如果不加修飾符,模塊中的成員訪問權(quán)將是私有的。這意味著,它們只能在定義它們的模塊內(nèi)部被訪問。如果想讓其他模塊能夠訪問某個(gè)成員,就需要在該模塊和該成員前加上pub關(guān)鍵字來聲明其為公開的。
訪問權(quán)限主要有兩種:一種是模塊級的訪問權(quán)限,另一種是成員級別的訪問權(quán)限。
1、模塊級的訪問權(quán)限。公開模塊可以在任何地方被訪問,只要我們知道正確的路徑。私有模塊只能在與其平級的位置,或下級的位置被訪問。也就是說,如果一個(gè)模塊是私有的,那么只有在其同級模塊或子模塊中才能引用它。
2、成員級別的訪問權(quán)限。使用pub關(guān)鍵字標(biāo)記的成員是公開的,可以在其他模塊中通過路徑來訪問。沒有使用pub關(guān)鍵字標(biāo)記的成員是私有的,只能在定義它們的模塊內(nèi)部訪問。
// 公開模塊 pub mod public_module { // 公開函數(shù),可以在其他模塊中訪問 pub fn public_function() { } // 私有函數(shù),只能在本模塊內(nèi)部訪問 fn private_function() { } } // 私有模塊 mod private_module { // 這個(gè)模塊是私有的,不能在其他模塊中直接訪問 fn private_function() { } } fn main() { public_module::public_function(); }
除此之外,Rust還提供了更細(xì)粒度的訪問控制,允許我們指定一個(gè)成員僅在crate內(nèi)部可見,或者僅在特定的模塊及其子模塊中可見。pub(crate)表示該成員在當(dāng)前crate的任何地方都可見,但在外部crate中不可見。pub(in module)表示該成員在指定的模塊及其子模塊中可見,在其他模塊不可見。
// 函數(shù)僅在當(dāng)前crate內(nèi)可見 pub(crate) fn crate_function() { } // 公開模塊 pub mod my_module { // 函數(shù)僅在當(dāng)前模塊及其子模塊中可見 pub(in crate::my_module) fn module_function() { } pub fn public_function() { // 可以調(diào)用crate_function crate::crate_function(); // 可以調(diào)用module_function module_function(); } } // 另一個(gè)模塊 mod another_module { pub fn another_function() { crate::crate_function(); // 下面的代碼會(huì)提示編譯錯(cuò)誤:function `module_function` is private super::my_module::module_function(); } } fn main() { crate_function(); }
如果模塊中定義了結(jié)構(gòu)體,那么結(jié)構(gòu)體本身以及它的字段默認(rèn)都是私有的。如果希望結(jié)構(gòu)體的某個(gè)字段能夠被外部訪問,則需要在結(jié)構(gòu)體和該字段前均加上pub關(guān)鍵字。枚舉類型則不同,只需要在枚舉類型前加上pub關(guān)鍵字,而不需要在枚舉成員前加上pub關(guān)鍵字。
使用use
use關(guān)鍵字用于導(dǎo)入模塊或庫中的元素(比如:函數(shù)、結(jié)構(gòu)體等),以便在當(dāng)前作用域中使用它們而無需使用完全限定的名稱。use語句通常放在文件的頂部,緊接在模塊聲明之后。
use關(guān)鍵字的使用方式主要以下幾種。
1、導(dǎo)入整個(gè)模塊??梢允褂胾se來導(dǎo)入整個(gè)模塊,這樣我們就可以直接使用該模塊中公開的成員。
// 導(dǎo)入std模塊中的vec模塊 use std::vec; fn main() { // 直接使用vec!宏 let value = vec![1, 2, 3]; println!("{:?}", value); }
2、導(dǎo)入特定項(xiàng)。可以使用use來導(dǎo)入模塊中的特定項(xiàng),而不是整個(gè)模塊。
// 只導(dǎo)入HashMap use std::collections::HashMap;
3、重命名導(dǎo)入的項(xiàng)。如果導(dǎo)入的元素在當(dāng)前作用域中已經(jīng)存在同名項(xiàng),或者想要使用不同的名稱來引用它,我們可以使用as關(guān)鍵字來重命名。
// 重命名HashMap為:MyMap use std::collections::HashMap as MyMap;
4、使用通配符導(dǎo)入。使用*可以導(dǎo)入模塊中所有公開的成員,但需要注意的是,過度使用通配符導(dǎo)入可能會(huì)導(dǎo)致名稱沖突和不可預(yù)見的行為,因此通常建議明確導(dǎo)入你需要的元素。
// 導(dǎo)入std::collections模塊中的所有公開成員 use std::collections::*;
5、多個(gè)use語句可以組合在一起,以提高便捷性和可讀性。
use std::{ fs::File, io::{self, Write}, };
總結(jié)
Rust的模塊系統(tǒng)是其代碼組織管理的核心部分,它提供了一種方式來封裝和組織代碼,控制作用域和路徑的私有性,以及導(dǎo)出公共接口。模塊系統(tǒng)使得開發(fā)者能夠構(gòu)建大型、復(fù)雜的應(yīng)用程序,同時(shí)保持代碼的清晰性和可維護(hù)性。
到此這篇關(guān)于Rust中箱、包和模塊的學(xué)習(xí)筆記的文章就介紹到這了,更多相關(guān)Rust 箱、包和模塊內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
利用Rust實(shí)現(xiàn)一個(gè)簡單的Ping應(yīng)用
這兩年Rust火的一塌糊涂,甚至都燒到了前端,再不學(xué)習(xí)怕是要落伍了。最近翻了翻文檔,寫了個(gè)簡單的Ping應(yīng)用練練手,感興趣的小伙伴可以了解一下2022-12-12Rust并發(fā)編程之使用消息傳遞進(jìn)行線程間數(shù)據(jù)共享方式
文章介紹了Rust中的通道(channel)概念,包括通道的基本概念、創(chuàng)建并使用通道、通道與所有權(quán)、發(fā)送多個(gè)消息以及多發(fā)送端,通道提供了一種線程間安全的通信機(jī)制,通過所有權(quán)規(guī)則確保數(shù)據(jù)安全,并且支持多生產(chǎn)者單消費(fèi)者架構(gòu)2025-02-02vscode搭建rust開發(fā)環(huán)境的圖文教程
Rust 是一種系統(tǒng)編程語言,它專注于內(nèi)存安全、并發(fā)和性能,本文主要介紹了vscode搭建rust開發(fā)環(huán)境的圖文教程,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03