<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
類似es6的模組化,Rust通過package、create、module來實現程式碼的模組化管理
Rust的程式碼組織包括:哪些細節可以暴露,哪些細節是私有的,作用域內哪些名稱有效等等。
create的型別:
其中,關於Create,還有個概念——Create Root:
是原始碼檔案Rust編譯器從這裡開始,組成你的Create的根Module
一個Package:
我們使用cargo新建一個專案
然後會提示: Created binary (application) my-project
package,這代表我們建立了一個二進位制的應用程式,名叫my-project
的package
我們進入這個資料夾:
我們可以看到src/min.rs檔案,這是我們程式的入口檔案,但是我們在Cargo.toml中並沒有看到相關的設定:
[package] name = "my-project" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies]
這是因為cargo有一些慣例
Cargo將會把create root檔案交給rustc(rust編譯器)來構建library或者binary
一個Package可以同時包含src/main.rs和src/lib.rs
一個Package也可以有多個binary create:
將相關功能組合到一個作用域內,便於在專案間進行共用。
同時,這也能防止命名衝突,例如rand create,存取它的功能需要通過它的名字:rand
Module:
建立module:
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() {}} }
src/main.rs 和 src/lib.rs 叫做create roots:
路徑的作用是為了在rust的模組中找到某個條目
路徑的兩種形式:
路徑至少由一個識別符號組成,識別符號之間使用::
。
舉個例子(下面這段程式將報錯,我們將在後面講到如何解決):
mod front_of_house {mod hosting {fn add_to_waitlist() {}} } pub fn eat_at_restaurant() {crate::front_of_house::hosting::add_to_waitlist();//絕對路徑front_of_house::hosting::add_to_waitlist();//相對路徑 }
那麼為什麼會報錯呢?
我們檢視報錯的原因:module hosting
is private,編譯器告訴我們,hosting這個module是私有的。至此,為了解決這個問題,我們應該去了解一下私有邊界。
為什麼rust預設這些條目是私有的呢?因為rust希望能夠隱藏內部的實現細節,這樣就會讓開發者明確知道:更改哪些內部程式碼的時候,不會破壞外部的程式碼。同時,我們可以使用pub關鍵字將其宣告為公共的。
rust預設這些條目為私有的,我們可以使用pub
關鍵字來將某些條目標記為公共的。
我們將hosting
宣告pub,add_to_waitlist
這個function也要宣告pub
mod front_of_house {pub mod hosting {pub fn add_to_waitlist() {}} } pub fn eat_at_restaurant() {crate::front_of_house::hosting::add_to_waitlist();//絕對路徑front_of_house::hosting::add_to_waitlist();//相對路徑 }
為什麼front_of_house
這個mod不需要新增pub呢?因為它們是同級的。
super:用來存取父級模組路徑中的內容,類似檔案系統中的..
fn serve_order() {} mod front_of_house {fn fix_incorrect_order() {cook_order();super::serve_order();}fn cook_order() {} }
宣告一個公共的struct就是將pub放在struct前:
mod back_of_house {pub struct Breakfast {} }
宣告了一個公共的struct後:
而我們想讓struct中的欄位為公有的必須在前面加上pub
:
mod back_of_house {pub struct Breakfast {pub toast: String,//公有的seasonal_fruit: String, //私有的} }
也就是說:struct的欄位需要單獨設定pub來變成公有
我們看一個例子:
mod back_of_house {pub struct Breakfast {pub toast: String,//公有的seasonal_fruit: String, //私有的}impl Breakfast {//一個關聯函數pub fn summer(toast: &str) -> Breakfast {Breakfast {toast: String::from(toast),seasonal_fruit: String::from("peaches"),}}} } pub fn eat_at_restaurant() {let mut meal = back_of_house::Breakfast::summer("Rye");meal.toast = String::from("Wheat");println!("I'd like {} toast please", meal.toast);meal.seasonal_fruit = String::from("blueberries");//報錯:field `seasonal_fruit` is private }
宣告一個公共的enum就是將pub放在enum前:
mod back_of_house {pub enum Appetizer {} }
我們宣告了一個公共的enum後:
mod back_of_house {pub enum Appetizer {Soup,//公共的Salad, //公共的} }
為什麼呢?因為列舉裡面只有變體,只有變體是公共的這個列舉才有用。而struct中某些部分為私有的也不影響struct的使用,所以rust規定公共的struct中的欄位預設為私有的。
我們可以使用use
關鍵字將路徑匯入到作用域內,而我們引入的東西也任然遵循私有性規則(公共的引入的才能用)
mod front_of_house {pub mod hosting {pub fn add_to_waitlist() {}fn some_function() {}//私有的,使用use匯入後,外部依然不能呼叫這個函數} } use crate::front_of_house::hosting; // 相當於mod hosting {} pub fn eat_at_restaurant() {hosting::add_to_waitlist();hosting::add_to_waitlist();hosting::add_to_waitlist(); }
使用use來指定相對路徑(和使用條目時的規則相同):
use front_of_house::hosting;
我們可以注意到我們呼叫的add_to_waitlist
是匯入的hosting
mod下的,那我們可不可以直接匯入function呢?
當然是可以的(不過並不推薦直接匯入方法):
mod front_of_house {pub mod hosting {pub fn add_to_waitlist() {}} } use crate::front_of_house::hosting::add_to_waitlist; // 相對於mod hosting {} pub fn eat_at_restaurant() {add_to_waitlist(); }
當我們直接匯入方法時,我們有可能就搞不清楚是從其他模組匯入的還是在這個作用域下宣告的。
所以,通常情況下,我們匯入的通常為父級模組。
//... use crate::front_of_house::hosting; pub fn eat_at_restaurant() {hosting::add_to_waitlist(); }
不過,struct,enum,其他:指定完整路徑(指定到本身)
use std::collections::HashMap; fn main() {let mut map = HashMap::new();map.insert(1, 2); }
但是同名的條目,我們在引入時需指定父級模組(比如下面的例子,兩個型別都叫Result)
use std::fmt; use std::io; fn f1() -> fmt::Result {//... } fn f2() -> io::Result {//... } //...
關於上面同名的問題,還有另一種解決方法:使用as關鍵字
as關鍵字可以為引入的路徑指定原生的別名
use std::fmt::Result; use std::io::Result as IoResult; fn f1() -> Result {//... } fn f2() -> IoResult {//... }
使用 use 將路徑(名稱)匯入到作用域內後,該名稱在此作用域內是私有的,外部的模組是沒辦法存取use匯入的模組的。
由前面pub的作用可知,類似pub fn、pub mod,我們可以使用pub use
來匯入,相當於它匯入了這個內容,然後又將它匯出了。
(當我們使用pub use時會發現沒有警告:“匯入了但沒有使用”,因為它同時也匯出了,也被視作使用了這個匯入的內容)
我們通過在Cargo.toml中的[dependencies]
新增依賴:
# ... [dependencies] rand = "^0.8.5"
出現:Blocking waiting for file lock on package cache
刪除User/.cargo資料夾中的.package-cache
檔案。重新執行cargo build
下載依賴。
很多時候我們的下載速度很慢,我們可以將下載源換到國內,在使用者資料夾下的.cargo
資料夾中新增 config 檔案,寫入以下內容:
[source.crates-io] registry = "https://github.com/rust-lang/crates.io-index" replace-with = 'ustc' [source.ustc] registry = "git://mirrors.ustc.edu.cn/crates.io-index" # 如果所處的環境中不允許使用 git 協定,可以把上面的地址改為 # registry = "https://mirrors.ustc.edu.cn/crates.io-index" #[http] #check-revoke = false
這時候cargo build就會很快了。
我們這樣匯入:
use rand::Rng;
另外:標準庫也被當做外部包,需要匯入,並且:
use std::{ascii, io}; //相當於:use std::ascii; // use std::io;
這樣的匯入該如何簡寫呢?
use std::io; use std::io::Chain;
可以使用self
use std::io::{self, Chain};
假如我們的src/lib.rs中的內容是這樣:
mod front_of_house {pub mod hosting {pub fn add_to_waitlist() {}} } //... mod front_of_house {pub mod hosting {pub fn add_to_waitlist() {}} } //...
我們可以在lib.rs同級目錄下新建front_of_house.rs
,然後將模組內容寫在檔案中:
front_of_house.rs
pub mod hosting {pub fn add_to_waitlist() {} }
lib.rs
mod front_of_house; //...
如果我們想將hosting
模組的內容單獨存放呢?
我們需要新建一個front_of_house資料夾,並新建hosting.rs檔案
hosting.rs
pub fn add_to_waitlist() {}
front_of_house.rs
pub mod hosting;
lib.rs
mod front_of_house;//...
原來的檔案內容:
mod front_of_house {pub mod hosting {pub fn add_to_waitlist() {}} }
隨著模組逐漸變大,這項功能將能夠幫助我們更好的管理程式碼
到此這篇關於Rust如何進行模組化開發的文章就介紹到這了,更多相關Rust模組化開發內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45