W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
ch07-02-defining-modules-to-control-scope-and-privacy.md
commit 310ea6cb0dd855eaf510c9ba05648bc5836ead0c
在本節(jié),我們將討論模塊和其它一些關(guān)于模塊系統(tǒng)的部分,如允許你命名項的 路徑(paths);用來將路徑引入作用域的 use
關(guān)鍵字;以及使項變?yōu)楣械?nbsp;pub
關(guān)鍵字。我們還將討論 as
關(guān)鍵字、外部包和 glob 運算符?,F(xiàn)在,讓我們把注意力放在模塊上!
首先,我們將從一系列的規(guī)則開始,在你未來組織代碼的時候,這些規(guī)則可被用作簡單的參考。接下來我們將會詳細的解釋每條規(guī)則。
這里我們提供一個簡單的參考,用來解釋模塊、路徑、use
關(guān)鍵詞和pub
關(guān)鍵詞如何在編譯器中工作,和大部分開發(fā)者如何組織他們的代碼。我們將在這個章節(jié)中對每條規(guī)則的例子一一列舉,但這是一個用來參考的好地方用于表達模塊是如何工作的。
mod garden
聲明了一個叫做garden
的模塊。編譯器會在下列路徑中尋找模塊代碼:mod garden
?后方不是一個分號而是一個大括號Asparagus
?類型可以在?crate::garden::vegetables::Asparagus
?被找到。pub mod
?替代?mod
?。為了使一個公用模塊內(nèi)部的成員公用,應(yīng)當(dāng)在聲明前使用?pub
?。use
?關(guān)鍵字創(chuàng)建了一個成員的快捷方式,用來減少長路徑的重復(fù)。在任何可以引用?crate::garden::vegetables::Asparagus
?的作用域, 你可以通過 ?use crate::garden::vegetables::Asparagus;
?創(chuàng)建一個快捷方式,然后你就可以在作用域中只寫?Asparagus
?來使用該類型。這里我們創(chuàng)建一個名為backyard
的二進制crate來說明這些規(guī)則。該crate的路徑同樣命名為backyard
,該路徑包含了這些文件和目錄:
backyard
├── Cargo.lock
├── Cargo.toml
└── src
├── garden
│ └── vegetables.rs
├── garden.rs
└── main.rs
這個例子中的crate根文件是src/main.rs,該文件包括了:
Filename: src/main.rs
use crate::garden::vegetables::Asparagus;
pub mod garden;
fn main() {
let plant = Asparagus {};
println!("I'm growing {:?}!", plant);
}
pub mod garden;
行告訴編譯器應(yīng)該包含在src/garden.rs文件中發(fā)現(xiàn)的代碼:
Filename: src/garden.rs
pub mod vegetables;
在此處, pub mod vegetables;
意味著在src/garden/vegetables.rs中的代碼也應(yīng)該被包括。這些代碼是:
#[derive(Debug)]
pub struct Asparagus {}
現(xiàn)在讓我們深入了解這些規(guī)則的細節(jié)并在實際中演示它們!
模塊 讓我們可以將一個 crate 中的代碼進行分組,以提高可讀性與重用性。模塊還可以控制項的 私有性,即項是可以被外部代碼使用的(public),還是作為一個內(nèi)部實現(xiàn)的內(nèi)容,不能被外部代碼使用(private)。
在餐飲業(yè),餐館中會有一些地方被稱之為 前臺(front of house),還有另外一些地方被稱之為 后臺(back of house)。前臺是招待顧客的地方,在這里,店主可以為顧客安排座位,服務(wù)員接受顧客下單和付款,調(diào)酒師會制作飲品。后臺則是由廚師工作的廚房,洗碗工的工作地點,以及經(jīng)理做行政工作的地方組成。
我們可以將函數(shù)放置到嵌套的模塊中,來使我們的 crate 結(jié)構(gòu)與實際的餐廳結(jié)構(gòu)相同。通過執(zhí)行 cargo new --lib restaurant
,來創(chuàng)建一個新的名為 restaurant
的庫。然后將示例 7-1 中所羅列出來的代碼放入 src/lib.rs 中,來定義一些模塊和函數(shù)。
文件名: src/lib.rs
mod front_of_house {
mod hosting {
fn add_to_waitlist() {}
fn seat_at_table() {}
}
mod serving {
fn take_order() {}
fn serve_order() {}
fn take_payment() {}
}
}
示例 7-1:一個包含了其他內(nèi)置了函數(shù)的模塊的 front_of_house
模塊
我們定義一個模塊,是以 mod
關(guān)鍵字為起始,然后指定模塊的名字(本例中叫做 front_of_house
),并且用花括號包圍模塊的主體。在模塊內(nèi),我們還可以定義其他的模塊,就像本例中的 hosting
和 serving
模塊。模塊還可以保存一些定義的其他項,比如結(jié)構(gòu)體、枚舉、常量、特性、或者函數(shù)。
通過使用模塊,我們可以將相關(guān)的定義分組到一起,并指出他們?yōu)槭裁聪嚓P(guān)。程序員可以通過使用這段代碼,更加容易地找到他們想要的定義,因為他們可以基于分組來對代碼進行導(dǎo)航,而不需要閱讀所有的定義。程序員向這段代碼中添加一個新的功能時,他們也會知道代碼應(yīng)該放置在何處,可以保持程序的組織性。
在前面我們提到了,src/main.rs
和 src/lib.rs
叫做 crate 根。之所以這樣叫它們是因為這兩個文件的內(nèi)容都分別在 crate 模塊結(jié)構(gòu)的根組成了一個名為 crate
的模塊,該結(jié)構(gòu)被稱為 模塊樹(module tree)。
示例 7-2 展示了示例 7-1 中的模塊樹的結(jié)構(gòu)。
crate
└── front_of_house
├── hosting
│ ├── add_to_waitlist
│ └── seat_at_table
└── serving
├── take_order
├── serve_order
└── take_payment
示例 7-2: 示例 7-1 中代碼的模塊樹
這個樹展示了一些模塊是如何被嵌入到另一個模塊的(例如,hosting
嵌套在 front_of_house
中)。這個樹還展示了一些模塊是互為 兄弟(siblings) 的,這意味著它們定義在同一模塊中(hosting
和 serving
被一起定義在 front_of_house
中)。繼續(xù)沿用家庭關(guān)系的比喻,如果一個模塊 A 被包含在模塊 B 中,我們將模塊 A 稱為模塊 B 的 子(child),模塊 B 則是模塊 A 的 父(parent)。注意,整個模塊樹都植根于名為 crate
的隱式模塊下。
這個模塊樹可能會令你想起電腦上文件系統(tǒng)的目錄樹;這是一個非常恰當(dāng)?shù)念惐?!就像文件系統(tǒng)的目錄,你可以使用模塊來組織你的代碼。并且,就像目錄中的文件,我們需要一種方法來找到模塊。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: