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