国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Rust】Rust學(xué)習(xí) 第七章使用包、Crate和模塊管理不斷增長(zhǎng)的項(xiàng)目

這篇具有很好參考價(jià)值的文章主要介紹了【Rust】Rust學(xué)習(xí) 第七章使用包、Crate和模塊管理不斷增長(zhǎng)的項(xiàng)目。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目前為止,我們編寫的程序都在一個(gè)文件的一個(gè)模塊中。伴隨著項(xiàng)目的增長(zhǎng),你可以通過將代碼分解為多個(gè)模塊和多個(gè)文件來組織代碼。一個(gè)包可以包含多個(gè)二進(jìn)制 crate 項(xiàng)和一個(gè)可選的 crate 庫。伴隨著包的增長(zhǎng),你可以將包中的部分代碼提取出來,做成獨(dú)立的 crate,這些 crate 則作為外部依賴項(xiàng)。

Rust 有許多功能可以讓你管理代碼的組織,包括哪些內(nèi)容可以被公開,哪些內(nèi)容作為私有部分,以及程序每個(gè)作用域中的名字。這些功能。這有時(shí)被稱為 “模塊系統(tǒng)(the module system)”,包括:

  • Packages): Cargo 的一個(gè)功能,它允許你構(gòu)建、測(cè)試和分享 crate。
  • Crates?:一個(gè)模塊的樹形結(jié)構(gòu),它形成了庫或二進(jìn)制項(xiàng)目。
  • 模塊Modules)和?use: 允許你控制作用域和路徑的私有性。
  • 路徑path):一個(gè)命名例如結(jié)構(gòu)體、函數(shù)或模塊等項(xiàng)的方式

7.1?包和crate

模塊系統(tǒng)的第一部分,我們將介紹包和 crate。crate 是一個(gè)二進(jìn)制項(xiàng)或者庫。crate root?是一個(gè)源文件,Rust 編譯器以它為起始點(diǎn),并構(gòu)成你的 crate 的根模塊。package) 是提供一系列功能的一個(gè)或者多個(gè) crate。一個(gè)包會(huì)包含有一個(gè)?Cargo.toml?文件,闡述如何去構(gòu)建這些 crate。

一個(gè)包中至多?只能?包含一個(gè)庫 crate(library crate);包中可以包含任意多個(gè)二進(jìn)制 crate(binary crate);包中至少包含一個(gè) crate,無論是庫的還是二進(jìn)制的。

emm......這話說的

一個(gè)包至少包含一個(gè)crate,其中,可以包含任意個(gè)二進(jìn)制crate、但最多只能包含一個(gè)庫crate

看看創(chuàng)建包的時(shí)候會(huì)發(fā)生什么

【Rust】Rust學(xué)習(xí) 第七章使用包、Crate和模塊管理不斷增長(zhǎng)的項(xiàng)目,Rust,rust,學(xué)習(xí),開發(fā)語言,keep studying,筆記

具體的文件夾是這樣的

【Rust】Rust學(xué)習(xí) 第七章使用包、Crate和模塊管理不斷增長(zhǎng)的項(xiàng)目,Rust,rust,學(xué)習(xí),開發(fā)語言,keep studying,筆記

當(dāng)我們輸入了這條命令,Cargo 會(huì)給我們的包創(chuàng)建一個(gè)?Cargo.toml?文件。查看?Cargo.toml?的內(nèi)容,會(huì)發(fā)現(xiàn)并沒有提到?src/main.rs因?yàn)?Cargo 遵循的一個(gè)約定:src/main.rs?就是一個(gè)與包同名的二進(jìn)制 crate 的 crate 根。同樣的,Cargo 知道如果包目錄中包含?src/lib.rs,則包帶有與其同名的庫 crate,且?src/lib.rs?是 crate 根。crate 根文件將由 Cargo 傳遞給?rustc?來實(shí)際構(gòu)建庫或者二進(jìn)制項(xiàng)目。

一個(gè)包至少包含一個(gè)crate,其中可以包含任意個(gè)二進(jìn)制crate、最多只能包含一個(gè)庫crate

src/main.rs是一個(gè)與包同名的二進(jìn)制crate(也是二進(jìn)制的根crate);

如果該目錄下還存在src/lib.rs,則該包下還有一個(gè)同名的庫crate(且src/lib.rs的crate庫)

注:這里lib.rs表示庫文件。滿足上述條件【一個(gè)包至少包含一個(gè)crate,其中可以包含任意個(gè)二進(jìn)制crate、最多只能包含一個(gè)庫crate

在此,我們有了一個(gè)只包含?src/main.rs?的包,意味著它只含有一個(gè)名為test05的二進(jìn)制 crate。如果一個(gè)包同時(shí)含有?src/main.rs?和?src/lib.rs,則它有兩個(gè) crate:一個(gè)庫和一個(gè)二進(jìn)制項(xiàng),且名字都與包相同。通過將文件放在?src/bin?目錄下,一個(gè)包可以擁有多個(gè)二進(jìn)制 crate:每個(gè)?src/bin?下的文件都會(huì)被編譯成一個(gè)獨(dú)立的二進(jìn)制 crate。

很繞

一個(gè) crate 會(huì)將一個(gè)作用域內(nèi)的相關(guān)功能分組到一起,使得該功能可以很方便地在多個(gè)項(xiàng)目之間共享。舉一個(gè)例子,在第二章使用的?rand?crate 提供了生成隨機(jī)數(shù)的功能。通過將?rand?crate 加入到我們項(xiàng)目的作用域中,我們就可以在自己的項(xiàng)目中使用該功能。rand?crate 提供的所有功能都可以通過該 crate 的名字:rand?進(jìn)行訪問。

將一個(gè) crate 的功能保持在其自身的作用域中,可以知曉一些特定的功能是在我們的 crate 中定義的還是在?rand?crate 中定義的,這可以防止?jié)撛诘臎_突。

7.2?定義模塊來控制作用域與私有性

模塊?讓我們可以將一個(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ù)放置到嵌套的模塊中,來使我們的 crate 結(jié)構(gòu)與實(shí)際的餐廳結(jié)構(gòu)相同。通過執(zhí)行?cargo new --lib restaurant,來創(chuàng)建一個(gè)新的名為?restaurant?的庫。

mod front_of_house {
    mod hosting {
        fn add_to_waitlist() {}
        fn seat_at_table() {}
    }

    mod serving {
        fn take_order() {}
        fn server_order() {}
        fn take_payment() {}
    }
}

定義一個(gè)模塊,是以?mod?關(guān)鍵字為起始,然后指定模塊的名字(本例中叫做?front_of_house),并且用花括號(hào)包圍模塊的主體。在模塊內(nèi),我們還可以定義其他的模塊,就像本例中的?hosting?和?serving?模塊。模塊還可以保存一些定義的其他項(xiàng),比如結(jié)構(gòu)體、枚舉、常量、特性、或者函數(shù)。

src/main.rs?和?src/lib.rs?叫做 crate 根。之所以這樣叫它們的原因是,這兩個(gè)文件的內(nèi)容都是一個(gè)從名為?crate?的模塊作為根的 crate 模塊結(jié)構(gòu),稱為?模塊樹module tree)。

模塊樹的結(jié)構(gòu)

crate
 └── front_of_house
     ├── hosting
     │   ├── add_to_waitlist
     │   └── seat_at_table
     └── serving
         ├── take_order
         ├── serve_order
         └── take_payment

這個(gè)樹展示了一些模塊是如何被嵌入到另一個(gè)模塊的(例如,hosting?嵌套在?front_of_house?中)。這個(gè)樹還展示了一些模塊是互為?兄弟siblings) 的,這意味著它們定義在同一模塊中(hosting?和?serving?被一起定義在?front_of_house?中)。繼續(xù)沿用家庭關(guān)系的比喻,如果一個(gè)模塊 A 被包含在模塊 B 中,我們將模塊 A 稱為模塊 B 的?child),模塊 B 則是模塊 A 的?parent)。注意,整個(gè)模塊樹都植根于名為?crate?的隱式模塊下。

7.3?路徑用于引用模塊樹中的項(xiàng)

路徑有兩種形式:

  • 絕對(duì)路徑absolute path)從 crate 根開始,以 crate 名或者字面值?crate?開頭。
  • 相對(duì)路徑relative path)從當(dāng)前模塊開始,以?self、super?或當(dāng)前模塊的標(biāo)識(shí)符開頭。

絕對(duì)路徑和相對(duì)路徑都后跟一個(gè)或多個(gè)由雙冒號(hào)(::)分割的標(biāo)識(shí)符。

如何調(diào)用?add_to_waitlist?函數(shù)?還是同樣的問題,add_to_waitlist?函數(shù)的路徑是什么?

修改一下src/lib.rs(這個(gè)編譯不成功)

mod front_of_house {
    mod hosting {
        fn add_to_waitlist() {}
    }
}

pub fn eat_at_restaurant() {
    // Absolute path
    crate::front_of_house::hosting::add_to_waitlist();

    // Relative path
    front_of_house::hosting::add_to_waitlist();
}

eat_at_restaurant?函數(shù)是我們 crate 庫的一個(gè)公共API,所以使用?pub?關(guān)鍵字來標(biāo)記它。

第一種方式,我們?cè)?eat_at_restaurant?中調(diào)用?add_to_waitlist?函數(shù),使用的是絕對(duì)路徑。add_to_waitlist?函數(shù)與?eat_at_restaurant?被定義在同一 crate 中,這意味著我們可以使用?crate?關(guān)鍵字為起始的絕對(duì)路徑。

第二種方式,我們?cè)?eat_at_restaurant?中調(diào)用?add_to_waitlist,使用的是相對(duì)路徑。這個(gè)路徑以?front_of_house?為起始,這個(gè)模塊在模塊樹中,與?eat_at_restaurant?定義在同一層級(jí)。與之等價(jià)的文件系統(tǒng)路徑就是?front_of_house/hosting/add_to_waitlist。以名稱為起始,意味著該路徑是相對(duì)路徑。

編譯會(huì)報(bào)錯(cuò)

【Rust】Rust學(xué)習(xí) 第七章使用包、Crate和模塊管理不斷增長(zhǎng)的項(xiàng)目,Rust,rust,學(xué)習(xí),開發(fā)語言,keep studying,筆記

錯(cuò)誤信息說?hosting?模塊是私有的。換句話說,我們擁有?hosting?模塊和?add_to_waitlist?函數(shù)的的正確路徑,但是 Rust 不讓我們使用,因?yàn)樗荒茉L問私有片段。

使用pub關(guān)鍵字暴露路徑

給上述代碼加上pub,依舊報(bào)錯(cuò),還需給函數(shù)也加上,私有性規(guī)則不但應(yīng)用于模塊,還應(yīng)用于結(jié)構(gòu)體、枚舉、函數(shù)和方法。

mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

pub fn eat_at_restaurant() {
    // Absolute path
    crate::front_of_house::hosting::add_to_waitlist();

    // Relative path
    front_of_house::hosting::add_to_waitlist();
}

在絕對(duì)路徑,我們從?crate,也就是 crate 根開始。然后 crate 根中定義了?front_of_house?模塊。front_of_house?模塊不是公有的,不過因?yàn)?eat_at_restaurant?函數(shù)與?front_of_house?定義于同一模塊中(即,eat_at_restaurant?和?front_of_house?是兄弟),我們可以從?eat_at_restaurant?中引用?front_of_house。接下來是使用?pub?標(biāo)記的?hosting?模塊。我們可以訪問?hosting?的父模塊,所以可以訪問?hosting。最后,add_to_waitlist?函數(shù)被標(biāo)記為?pub?,我們可以訪問其父模塊,所以這個(gè)函數(shù)調(diào)用是有效的!

在相對(duì)路徑,其邏輯與絕對(duì)路徑相同,除了第一步:不同于從 crate 根開始,路徑從?front_of_house?開始。front_of_house?模塊與?eat_at_restaurant?定義于同一模塊,所以從?eat_at_restaurant?中開始定義的該模塊相對(duì)路徑是有效的。接下來因?yàn)?hosting?和?add_to_waitlist?被標(biāo)記為?pub,路徑其余的部分也是有效的,因此函數(shù)調(diào)用也是有效的!

使用 super 起始的相對(duì)路徑

還可以使用?super?開頭來構(gòu)建從父模塊開始的相對(duì)路徑。這么做類似于文件系統(tǒng)中以?..?開頭的語法。

下面代碼模擬了廚師更正了一個(gè)錯(cuò)誤訂單,并親自將其提供給客戶的情況。

mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

pub fn eat_at_restaurant() {
    // Absolute path
    crate::front_of_house::hosting::add_to_waitlist();

    // Relative path
    front_of_house::hosting::add_to_waitlist();
}


// 加了這段
fn serve_order() {}
mod back_of_house {
    fn fix_incorrect_order() {
        cook_order();
        super::serve_order();
    }
    fn cook_order() {}
}

fix_incorrect_order?函數(shù)在?back_of_house?模塊中,所以我們可以使用?super?進(jìn)入?back_of_house?父模塊,也就是本例中的?crate?根。在這里,我們可以找到?serve_order。成功!我們認(rèn)為?back_of_house?模塊和?server_order?函數(shù)之間可能具有某種關(guān)聯(lián)關(guān)系,并且,如果我們要重新組織這個(gè) crate 的模塊樹,需要一起移動(dòng)它們。

創(chuàng)建公有的結(jié)構(gòu)體和枚舉

還可以使用?pub?來設(shè)計(jì)公有的結(jié)構(gòu)體和枚舉,不過有一些額外的細(xì)節(jié)需要注意。如果在一個(gè)結(jié)構(gòu)體定義的前面使用了?pub?,這個(gè)結(jié)構(gòu)體會(huì)變成公有的,但是這個(gè)結(jié)構(gòu)體的字段仍然是私有的。可以根據(jù)情況決定每個(gè)字段是否公有。

與之相反,如果將枚舉設(shè)為公有,則它的所有成員都將變?yōu)楣?。只需要?enum?關(guān)鍵字前面加上?pub

7.4?使用use關(guān)鍵字將名稱引入作用域

導(dǎo)入頭文件???

到目前為止,似乎編寫的用于調(diào)用函數(shù)的路徑都很冗長(zhǎng)且重復(fù),并不方便。無論我們選擇?add_to_waitlist?函數(shù)的絕對(duì)路徑還是相對(duì)路徑,每次想要調(diào)用?add_to_waitlist?時(shí),都必須指定front_of_house?和?hosting。幸運(yùn)的是,有一種方法可以簡(jiǎn)化這個(gè)過程??梢砸淮涡詫⒙窂揭胱饔糜颍缓笫褂?use?關(guān)鍵字調(diào)用該路徑中的項(xiàng),就如同它們是本地項(xiàng)一樣。

mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
    // Absolute path
    hosting::add_to_waitlist();

    // Relative path
    hosting::add_to_waitlist();
}

通過?use?引入作用域的路徑也會(huì)檢查私有性,同其它路徑一樣。

創(chuàng)建慣用的use路徑

要想使用?use?將函數(shù)的父模塊引入作用域,必須在調(diào)用函數(shù)時(shí)指定父模塊,這樣可以清晰地表明函數(shù)不是在本地定義的,同時(shí)使完整路徑的重復(fù)度最小化。

另一方面,使用?use?引入結(jié)構(gòu)體、枚舉和其他項(xiàng)時(shí),習(xí)慣是指定它們的完整路徑。

使用as關(guān)鍵字提供新的名稱

使用?use?將兩個(gè)同名類型引入同一作用域這個(gè)問題還有另一個(gè)解決辦法:在這個(gè)類型的路徑后面,我們使用?as?指定一個(gè)新的本地名稱或者別名

#![allow(unused_variables)]
fn main() {
use std::fmt::Result;
use std::io::Result as IoResult;

fn function1() -> Result {
    // --snip--
    Ok(())
}

fn function2() -> IoResult<()> {
    // --snip--
    Ok(())
}
}

使用外部包

crates.io?上有很多 Rust 社區(qū)成員發(fā)布的包,將其引入你自己的項(xiàng)目都需要一道相同的步驟:在?Cargo.toml?列出它們并通過?use?將其中定義的項(xiàng)引入項(xiàng)目包的作用域中。

注意標(biāo)準(zhǔn)庫(std)對(duì)于你的包來說也是外部 crate。因?yàn)闃?biāo)準(zhǔn)庫隨 Rust 語言一同分發(fā),無需修改?Cargo.toml?來引入?std,不過需要通過?use?將標(biāo)準(zhǔn)庫中定義的項(xiàng)引入項(xiàng)目包的作用域中來引用它們,比如我們使用的?HashMap

#![allow(unused_variables)]
fn main() {
use std::collections::HashMap;
}

嵌套路徑來消除大量的 use 行

use std::cmp::Ordering;
use std::io;

可以寫成

use std::{cmp::Ordering, io};

在較大的程序中,使用嵌套路徑從相同包或模塊中引入很多項(xiàng),可以顯著減少所需的獨(dú)立?use?語句的數(shù)量!

use std::io;
use std::io::Write;

可以寫成

use std::io::{self, Write};

通過 glob 運(yùn)算符將所有的公有定義引入作用域

如果希望將一個(gè)路徑下?所有?公有項(xiàng)引入作用域,可以指定路徑后跟?*,glob 運(yùn)算符:

use std::collections::*;

這個(gè)?use?語句將?std::collections?中定義的所有公有項(xiàng)引入當(dāng)前作用域。使用 glob 運(yùn)算符時(shí)請(qǐng)多加小心!Glob 會(huì)使得我們難以推導(dǎo)作用域中有什么名稱和它們是在何處定義的。

7.5?將模塊分割進(jìn)不同文件

上述案例中,將?front_of_house?模塊移動(dòng)到屬于它自己的文件?src/front_of_house.rs?中,通過改變 crate 根文件。crate 根文件是?src/lib.rs,這也同樣適用于以?src/main.rs?為 crate 根文件的二進(jìn)制 crate 項(xiàng)。

文件名: src/lib.rs

mod front_of_house;

pub use crate::front_of_house::hosting;

pub fn eat_at_restaurant() {
    hosting::add_to_waitlist();
    hosting::add_to_waitlist();
    hosting::add_to_waitlist();
}

聲明?front_of_house?模塊,其內(nèi)容位于?src/front_of_house.rs

pub mod hosting {
    pub fn add_to_waitlist() {}
}

接著我們創(chuàng)建一個(gè)?src/front_of_house?目錄和一個(gè)包含?hosting?模塊定義的?src/front_of_house/hosting.rs?文件:

pub fn add_to_waitlist() {}

模塊樹依然保持相同,eat_at_restaurant?中的函數(shù)調(diào)用也無需修改繼續(xù)保持有效,即便其定義存在于不同的文件中。這個(gè)技巧讓你可以在模塊代碼增長(zhǎng)時(shí),將它們移動(dòng)到新文件中。

注意,src/lib.rs?中的?pub use crate::front_of_house::hosting?語句是沒有改變的,在文件作為 crate 的一部分而編譯時(shí),use?不會(huì)有任何影響。mod?關(guān)鍵字聲明了模塊,Rust 會(huì)在與模塊同名的文件中查找模塊的代碼。

【Rust】Rust學(xué)習(xí) 第七章使用包、Crate和模塊管理不斷增長(zhǎng)的項(xiàng)目,Rust,rust,學(xué)習(xí),開發(fā)語言,keep studying,筆記

總結(jié)

Rust 提供了將包組織進(jìn) crate、將 crate 組織進(jìn)模塊,和通過指定絕對(duì)或相對(duì)路徑從一個(gè)模塊引用另一個(gè)模塊中定義的項(xiàng)的方式。你可以通過使用?use?語句將路徑引入作用域,這樣在多次使用時(shí)可以使用更短的路徑。模塊定義的代碼默認(rèn)是私有的,不過可以選擇增加?pub?關(guān)鍵字使其定義變?yōu)楣小?mark hidden color="red">文章來源:http://www.zghlxwxcb.cn/news/detail-637234.html

參考:使用包、Crate 和模塊管理不斷增長(zhǎng)的項(xiàng)目 - Rust 程序設(shè)計(jì)語言 簡(jiǎn)體中文版 (bootcss.com)文章來源地址http://www.zghlxwxcb.cn/news/detail-637234.html

到了這里,關(guān)于【Rust】Rust學(xué)習(xí) 第七章使用包、Crate和模塊管理不斷增長(zhǎng)的項(xiàng)目的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包