欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Rust如何進(jìn)行模塊化開(kāi)發(fā)技巧分享

 更新時(shí)間:2023年01月15日 14:38:39   作者:前端開(kāi)發(fā)小陳  
Rust模塊化,模塊化有助于代碼的管理和層次邏輯的清晰,本文主要介紹了Rust如何進(jìn)行模塊化開(kāi)發(fā),結(jié)合實(shí)例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下

類似es6的模塊化,Rust通過(guò)package、create、module來(lái)實(shí)現(xiàn)代碼的模塊化管理

Rust如何進(jìn)行模塊化開(kāi)發(fā)?

Rust的代碼組織包括:哪些細(xì)節(jié)可以暴露,哪些細(xì)節(jié)是私有的,作用域內(nèi)哪些名稱有效等等。

  • Package(包):Cargo的特性,讓你構(gòu)建、測(cè)試、共享create
  • Create(單元包):一個(gè)模塊樹(shù),它可以產(chǎn)生一個(gè)library或可執(zhí)行文件
  • Module(模塊)、use:讓你控制代碼的組織、作用域、私有路徑
  • Path(路徑):為struct、function或module等項(xiàng)命名的方式

Package和Create

create的類型:

  • binary(二進(jìn)制create)
  • library(庫(kù)create)

其中,關(guān)于Create,還有個(gè)概念——Create Root:

是源代碼文件Rust編譯器從這里開(kāi)始,組成你的Create的根Module

一個(gè)Package:

  • 包含一個(gè)Cargo.toml,它描述了如何構(gòu)建這些Crates
  • 只能包含0-1個(gè)library create(庫(kù)create)
  • 可以包含任意數(shù)量的binary create(二進(jìn)制create)
  • 但必須至少包含一個(gè)create(library或binary)

我們使用cargo新建一個(gè)項(xiàng)目

然后會(huì)提示: Created binary (application) my-project package,這代表我們創(chuàng)建了一個(gè)二進(jìn)制的應(yīng)用程序,名叫my-project的package

我們進(jìn)入這個(gè)文件夾:

我們可以看到src/min.rs文件,這是我們程序的入口文件,但是我們?cè)贑argo.toml中并沒(méi)有看到相關(guān)的配置:

[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] 

這是因?yàn)閏argo有一些慣例

Cargo的慣例

  • src/main.rs是binary create的create root* create的名與package名相同如果我們還有一個(gè)這個(gè)文件:src/lib.rs,那么:
  • 表明package包含一個(gè)library create
  • 它是library create的create root
  • create的名與package名相同

Cargo將會(huì)把create root文件交給rustc(rust編譯器)來(lái)構(gòu)建library或者binary

一個(gè)Package可以同時(shí)包含src/main.rs和src/lib.rs

一個(gè)Package也可以有多個(gè)binary create:

  • 文件放在src/bin,放在這里的每個(gè)文件都是單獨(dú)的binary create

Create的作用

將相關(guān)功能組合到一個(gè)作用域內(nèi),便于在項(xiàng)目間進(jìn)行共享。

同時(shí),這也能防止命名沖突,例如rand create,訪問(wèn)它的功能需要通過(guò)它的名字:rand

定義module來(lái)控制作用域和私有性

Module:

  • 在一個(gè)create內(nèi),將代碼進(jìn)行分組
  • 增加可讀性,易于復(fù)用
  • 控制項(xiàng)目(item)的私有性。public,private

建立module:

  • mod關(guān)鍵字
  • 可嵌套
  • 可包含其他項(xiàng)(struct、enum、常量、trait、函數(shù)等)的定義
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:

  • 這兩個(gè)文件(任意一個(gè))的內(nèi)容形成了名為create的模塊,位于整個(gè)模塊樹(shù)的根部
  • 整個(gè)模塊樹(shù)在隱式的模塊下

路徑Path

路徑的作用是為了在rust的模塊中找到某個(gè)條目

路徑的兩種形式:

  • 絕對(duì)路徑:從create root開(kāi)始,使用create名或字面值create
  • 相對(duì)路徑:從當(dāng)前模塊開(kāi)始,使用self(本身),super(上一級(jí))或當(dāng)前模塊的標(biāo)識(shí)符

路徑至少由一個(gè)標(biāo)識(shí)符組成,標(biāo)識(shí)符之間使用::。

舉個(gè)例子(下面這段程序?qū)?bào)錯(cuò),我們將在后面講到如何解決):

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

pub fn eat_at_restaurant() {crate::front_of_house::hosting::add_to_waitlist();//絕對(duì)路徑front_of_house::hosting::add_to_waitlist();//相對(duì)路徑
} 

那么為什么會(huì)報(bào)錯(cuò)呢?

我們查看報(bào)錯(cuò)的原因:module hosting is private,編譯器告訴我們,hosting這個(gè)module是私有的。至此,為了解決這個(gè)問(wèn)題,我們應(yīng)該去了解一下私有邊界。

私有邊界(private boundary)

  • 模塊不僅可以組織代碼,還可以定義私有邊界
  • 如果把函數(shù)或struct等設(shè)為私有,可以將它放到某個(gè)模塊中。
  • rust中所有的條目(函數(shù),方法,struct,enum,模塊,常量)默認(rèn)情況下是私有的
  • 父級(jí)模塊無(wú)法訪問(wèn)子模塊中的私有條目
  • 但是在子模塊中可以使用所有祖先模塊中的條目

為什么rust默認(rèn)這些條目是私有的呢?因?yàn)閞ust希望能夠隱藏內(nèi)部的實(shí)現(xiàn)細(xì)節(jié),這樣就會(huì)讓開(kāi)發(fā)者明確知道:更改哪些內(nèi)部代碼的時(shí)候,不會(huì)破壞外部的代碼。同時(shí),我們可以使用pub關(guān)鍵字將其聲明為公共的。

pub關(guān)鍵字

rust默認(rèn)這些條目為私有的,我們可以使用pub關(guān)鍵字來(lái)將某些條目標(biāo)記為公共的。

我們將hosting聲明pub,add_to_waitlist這個(gè)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();//絕對(duì)路徑front_of_house::hosting::add_to_waitlist();//相對(duì)路徑
} 

為什么front_of_house這個(gè)mod不需要添加pub呢?因?yàn)樗鼈兪峭?jí)的。

super關(guān)鍵字

super:用來(lái)訪問(wèn)父級(jí)模塊路徑中的內(nèi)容,類似文件系統(tǒng)中的..

fn serve_order() {}
mod front_of_house {fn fix_incorrect_order() {cook_order();super::serve_order();}fn cook_order() {}
} 

pub struct

聲明一個(gè)公共的struct就是將pub放在struct前:

mod back_of_house {pub struct Breakfast {}
} 

聲明了一個(gè)公共的struct后:

  • struct是公共的
  • struct的字段默認(rèn)是私有的

而我們想讓struct中的字段為公有的必須在前面加上pub

mod back_of_house {pub struct Breakfast {pub toast: String,//公有的seasonal_fruit: String, //私有的}
} 

也就是說(shuō):struct的字段需要單獨(dú)設(shè)置pub來(lái)變成公有

我們看一個(gè)例子:

mod back_of_house {pub struct Breakfast {pub toast: String,//公有的seasonal_fruit: String, //私有的}impl Breakfast {//一個(gè)關(guān)聯(lián)函數(shù)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");//報(bào)錯(cuò):field `seasonal_fruit` is private
} 

pub enum

聲明一個(gè)公共的enum就是將pub放在enum前:

mod back_of_house {pub enum Appetizer {}
} 

我們聲明了一個(gè)公共的enum后:

  • enum是公共的
  • enum的變體也都是公共的
mod back_of_house {pub enum Appetizer {Soup,//公共的Salad, //公共的}
} 

為什么呢?因?yàn)槊杜e里面只有變體,只有變體是公共的這個(gè)枚舉才有用。而struct中某些部分為私有的也不影響struct的使用,所以rust規(guī)定公共的struct中的字段默認(rèn)為私有的。

Use關(guān)鍵字

我們可以使用use關(guān)鍵字將路徑導(dǎo)入到作用域內(nèi),而我們引入的東西也任然遵循私有性規(guī)則(公共的引入的才能用)

mod front_of_house {pub mod hosting {pub fn add_to_waitlist() {}fn some_function() {}//私有的,使用use導(dǎo)入后,外部依然不能調(diào)用這個(gè)函數(shù)}
}

use crate::front_of_house::hosting;
// 相當(dāng)于mod hosting {}

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

使用use來(lái)指定相對(duì)路徑(和使用條目時(shí)的規(guī)則相同):

use front_of_house::hosting; 

我們可以注意到我們調(diào)用的add_to_waitlist是導(dǎo)入的hostingmod下的,那我們可不可以直接導(dǎo)入function呢?

當(dāng)然是可以的(不過(guò)并不推薦直接導(dǎo)入方法):

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

use crate::front_of_house::hosting::add_to_waitlist;
// 相對(duì)于mod hosting {}

pub fn eat_at_restaurant() {add_to_waitlist();
} 

use的習(xí)慣用法

當(dāng)我們直接導(dǎo)入方法時(shí),我們有可能就搞不清楚是從其他模塊導(dǎo)入的還是在這個(gè)作用域下聲明的。

所以,通常情況下,我們導(dǎo)入的通常為父級(jí)模塊。

//...
use crate::front_of_house::hosting;

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

不過(guò),struct,enum,其他:指定完整路徑(指定到本身)

use std::collections::HashMap;
fn main() {let mut map = HashMap::new();map.insert(1, 2);
} 

但是同名的條目,我們?cè)谝霑r(shí)需指定父級(jí)模塊(比如下面的例子,兩個(gè)類型都叫Result)

use std::fmt;
use std::io;

fn f1() -> fmt::Result {//...
}

fn f2() -> io::Result {//...
}
//... 

as關(guān)鍵字

關(guān)于上面同名的問(wèn)題,還有另一種解決方法:使用as關(guān)鍵字

as關(guān)鍵字可以為引入的路徑指定本地的別名

use std::fmt::Result;
use std::io::Result as IoResult;

fn f1() -> Result {//...
}

fn f2() -> IoResult {//...
} 

使用 pub use 重新導(dǎo)出名稱

使用 use 將路徑(名稱)導(dǎo)入到作用域內(nèi)后,該名稱在此作用域內(nèi)是私有的,外部的模塊是沒(méi)辦法訪問(wèn)use導(dǎo)入的模塊的。

由前面pub的作用可知,類似pub fn、pub mod,我們可以使用pub use來(lái)導(dǎo)入,相當(dāng)于它導(dǎo)入了這個(gè)內(nèi)容,然后又將它導(dǎo)出了。

(當(dāng)我們使用pub use時(shí)會(huì)發(fā)現(xiàn)沒(méi)有警告:“導(dǎo)入了但沒(méi)有使用”,因?yàn)樗瑫r(shí)也導(dǎo)出了,也被視作使用了這個(gè)導(dǎo)入的內(nèi)容)

導(dǎo)入外部包

我們通過(guò)在Cargo.toml中的[dependencies]添加依賴:

# ...
[dependencies]
rand = "^0.8.5" 

出現(xiàn):Blocking waiting for file lock on package cache

刪除User/.cargo文件夾中的.package-cache文件。重新執(zhí)行cargo build下載依賴。

很多時(shí)候我們的下載速度很慢,我們可以將下載源換到國(guó)內(nèi),在用戶文件夾下的.cargo文件夾中添加 config 文件,寫(xiě)入以下內(nèi)容:

[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"
# 如果所處的環(huán)境中不允許使用 git 協(xié)議,可以把上面的地址改為
# registry = "https://mirrors.ustc.edu.cn/crates.io-index"
#[http]
#check-revoke = false 

這時(shí)候cargo build就會(huì)很快了。

我們這樣導(dǎo)入:

use rand::Rng; 

另外:標(biāo)準(zhǔn)庫(kù)也被當(dāng)做外部包,需要導(dǎo)入,并且:

  • 我們不需要修改Cargo.toml來(lái)添加依賴
  • 需要使用use將std的特定條目導(dǎo)入到當(dāng)前作用域 use多次導(dǎo)入(嵌套導(dǎo)入)
use std::{ascii, io};
//相當(dāng)于:use std::ascii;
// use std::io; 

這樣的導(dǎo)入該如何簡(jiǎn)寫(xiě)呢?

use std::io;
use std::io::Chain; 

可以使用self

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

如何將模塊放入其他文件?

假如我們的src/lib.rs中的內(nèi)容是這樣:

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同級(jí)目錄下新建front_of_house.rs,然后將模塊內(nèi)容寫(xiě)在文件中:

front_of_house.rs

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

lib.rs

mod front_of_house;
//... 

如果我們想將hosting模塊的內(nèi)容單獨(dú)存放呢?

我們需要新建一個(gè)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;//... 

原來(lái)的文件內(nèi)容:

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

隨著模塊逐漸變大,這項(xiàng)功能將能夠幫助我們更好的管理代碼

到此這篇關(guān)于Rust如何進(jìn)行模塊化開(kāi)發(fā)的文章就介紹到這了,更多相關(guān)Rust模塊化開(kāi)發(fā)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Rust字符串匹配Rabin-Karp算法詳解

    Rust字符串匹配Rabin-Karp算法詳解

    Rabin-Karp算法也可以叫 Karp-Rabin 算法,它是用來(lái)解決多模式串匹配問(wèn)題的,它的實(shí)現(xiàn)方式有點(diǎn)與眾不同,首先是計(jì)算兩個(gè)字符串的哈希值,然后通過(guò)比較這兩個(gè)哈希值的大小來(lái)判斷是否出現(xiàn)匹配,本文詳細(xì)介紹了字符串匹配Rabin-Karp算法,需要的朋友可以參考下
    2023-05-05
  • Rust版本號(hào)的使用方法詳解

    Rust版本號(hào)的使用方法詳解

    在 Rust 項(xiàng)目中,版本號(hào)的使用遵循語(yǔ)義版本控制(Semantic Versioning)原則,確保版本號(hào)的變化能準(zhǔn)確反映代碼的變更情況,本文給大家詳細(xì)解釋了Rust版本號(hào)用法,需要的朋友可以參考下
    2024-01-01
  • Rust 中解析 JSON的方法

    Rust 中解析 JSON的方法

    要開(kāi)始在 Rust 中使用 JSON,您需要安裝一個(gè)可以輕松操作 JSON 的庫(kù),目前可用的流行crate之一是 serde-json,在本文中,我們將討論如何在 Rust 中使用 JSON 解析庫(kù),以及比較最流行的庫(kù)及其性能
    2024-03-03
  • rust實(shí)現(xiàn)post小程序(完整代碼)

    rust實(shí)現(xiàn)post小程序(完整代碼)

    這篇文章主要介紹了rust實(shí)現(xiàn)一個(gè)post小程序,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • Rust實(shí)現(xiàn)grep命令行工具的方法

    Rust實(shí)現(xiàn)grep命令行工具的方法

    這篇文章主要介紹了Rust實(shí)現(xiàn)grep命令行工具的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • 2022最新Rust變量與數(shù)據(jù)類型講解

    2022最新Rust變量與數(shù)據(jù)類型講解

    rust 是強(qiáng)類型語(yǔ)言所有變量、常量都必須有明確的數(shù)據(jù)類型,這篇文章主要介紹了Rust變量與數(shù)據(jù)類型,需要的朋友可以參考下
    2022-11-11
  • Rust中的Cargo構(gòu)建、運(yùn)行、調(diào)試

    Rust中的Cargo構(gòu)建、運(yùn)行、調(diào)試

    Cargo是rustup安裝后自帶的,Cargo?是?Rust?的構(gòu)建系統(tǒng)和包管理器,這篇文章主要介紹了Rust之Cargo構(gòu)建、運(yùn)行、調(diào)試,需要的朋友可以參考下
    2022-09-09
  • 聊聊Rust 運(yùn)算符

    聊聊Rust 運(yùn)算符

    運(yùn)算符 用于對(duì)數(shù)據(jù)執(zhí)行一些操作。被運(yùn)算符執(zhí)行操作的數(shù)據(jù)我們稱之為操作數(shù)。下面通過(guò)本文給大家介紹Rust 運(yùn)算符的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2021-11-11
  • Rust中non_exhaustive的enum使用確保程序健壯性

    Rust中non_exhaustive的enum使用確保程序健壯性

    這篇文章主要為大家介紹了Rust中non_exhaustive的enum使用確保程序健壯性示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • 最新Rust錯(cuò)誤處理簡(jiǎn)介

    最新Rust錯(cuò)誤處理簡(jiǎn)介

    Rust并不像C++一樣使用try?catch的異常機(jī)制來(lái)進(jìn)行錯(cuò)誤處理,他將錯(cuò)誤分為可恢復(fù)錯(cuò)誤和不可恢復(fù)錯(cuò)誤兩類,主要使用panic!宏和Result<T,E>類型來(lái)進(jìn)行錯(cuò)誤處理,這篇文章主要介紹了Rust錯(cuò)誤處理簡(jiǎn)介,需要的朋友可以參考下
    2022-11-11

最新評(píng)論