包管理(Cargo)
cargo 命令創(chuàng)建包
cargo new xxx --lib 創(chuàng)建一個名為xxx的包;
cargo new xxx 或者 cargo new xxx --bin 創(chuàng)建一個名為xxx的可被編譯為可執(zhí)行文件的包。
使用第三方包
- 在
Cargo.toml中的[dependencies]下加入包的依賴; - 在需要引入的文件頭部加入
extern crate包名; 之后才可以use包(Rust 2015)。在2018中,直接可以用use xxx。
Note:Cargo默認把連字符替換為下劃線。
Cargo文件格式
[package]表配置
描述的都是與包相關的元數(shù)據(jù),比如包名,作者等。數(shù)組使用[],多段文字使用"""。
build = "buidl.rs" 指定構建腳本; workspace = ".." 指定工作空間為父目錄。
[badges]表配置
云端的持續(xù)集成服務。
[workspace]表配置
members = ["bench", "regex-capi"] 指定子包。
[dependencies]表配置
配置依賴文件。
[features]表配置
條件編譯功能相關。在代碼中對應#[cfg(featrue = "xxx")]。
[lib]表配置
表示最終編譯目標庫的信息:name,crate-type, path, test, bench等。
[ [test] ]表配置
用兩個中括號,表示數(shù)組。
[profile]表配置
自定義rustc編譯配置。
模塊系統(tǒng)
如果存在與文件名同名的目錄,則該目錄下的模塊都是該文件的子模塊。

read_func.rs
pub mod static_kv; //pub關鍵字使得可以在main.rs中:use read_func::static_kv
pub fn read_kv () {
}
pub fn rw_mut_kv() -> Result<(), String> {
}
Rust會通過mod關鍵字去當前模塊的子模塊中尋找static_kv模塊。模塊名字可以被以下表述:1.模塊名.rs;2.與模塊名相同的文件夾,并且該文件夾包含mod.rs。
read_func/static_kv.rs
use lazy_static::lazy_static;
use std::collections::HashMap;
use std::sync::RwLock;
main.rs
mod read_func;
use crate::read_func::{read_kv , rw_mut_kv}; //因為之前聲明了pub
fn main() {
}
第一行mod引入模塊。
第二行的crate可以用self代替,代表當前的crate,以main.rs為起點尋找當前相對路徑下的read_func模塊。如果是第三方包,就不需要寫crate前綴。
模塊間的關系
模塊嵌套
mod sound {
mod instrument {
mod woodwind {
fn clarinet() {
// 函數(shù)體
}
}
}
mod voice {
}
}
fn main() {
}
樹形結構:
crate
└── sound
├── instrument
│ └── woodwind
└── voice
私有性規(guī)則有如下:
- 所有項(函數(shù)、方法、結構體、枚舉、模塊和常量)默認是私有的。
- 可以使用 pub 關鍵字使項變?yōu)楣小?/li>
- 不允許使用定義于當前模塊的子模塊中的私有代碼。
- 允許使用任何定義于父模塊或當前模塊中的代碼。
mod sound {
pub mod instrument { //加上Pub后可用路徑訪問instrument
pub fn clarinet() { //加上pub后可以用該函數(shù)
// 函數(shù)體
}
}
}
fn main() {
// 絕對路徑
crate::sound::instrument::clarinet();
// 相對路徑
sound::instrument::clarinet();
}
也可以使用 super 開頭來構建相對路徑。這么做類似于文件系統(tǒng)中以 .. 開頭:該路徑從 父 模塊開始而不是當前模塊。
mod instrument {
fn clarinet() {
super::breathe_in();
}
}
fn breathe_in() {
// 函數(shù)體
}
clarinet函數(shù)位于instrument 模塊中,所以可以使用 super 進入 instrument 的父模塊,也就是根 crate。從這里可以找到 breathe_in。使用super相對路徑可以方便的進行擴展,而不用更改路徑來調用。
sound模塊放入sound.rs文件中,調用方式不變。
重新導出
pub use crate::sound::instrument;
可以簡化外部調用的導出路徑(外部調用:use xxx::instrument;),也不需要對外暴露模塊(sound)。
一般重新導出放在lib.rs中。main.rs結合lib.rs的形式,是二進制包的最佳實踐。
可見性
pub mod outer_mod {
pub(self) fn outer_mod_fn() {}
pub mod inner_mod {
// 在Rust 2018 edtion 模塊系統(tǒng)必須使用use導入
use crate::outer_mod::outer_mod_fn;
// 對外層模塊 `outer_mod` 可見
pub(in crate::outer_mod) fn outer_mod_visible_fn() {}
// 對整個crate可見
pub(crate) fn crate_visible_fn() {}
// `outer_mod` 內部可見
pub(super) fn super_mod_visible_fn() {
// 訪問同一模塊的函數(shù)
inner_mod_visible_fn();
// 使用use導入了outer_mod
outer_mod_fn();
}
// 僅在`inner_mod`可見
pub(self) fn inner_mod_visible_fn() {}
}
pub fn foo() {
inner_mod::outer_mod_visible_fn();
inner_mod::crate_visible_fn();
inner_mod::super_mod_visible_fn();
// 不能使用inner_mod 的私有函數(shù)
// inner_mod::inner_mod_visible_fn();
}
}
fn bar() {
// 該函數(shù)對整個crate可見
outer_mod::inner_mod::crate_visible_fn();
// 該函數(shù)只對outer_mod可見
// outer_mod::inner_mod::super_mod_visible_fn();
// 該函數(shù)只對outer_mod可見
// outer_mod::inner_mod::outer_mod_visible_fn();
// 通過foo函數(shù)調用內部細節(jié)
outer_mod::foo();
}
fn main() { bar() }
關于pub:
- 如果不顯示使用pub,則函數(shù)或者模塊可見性默認為私有的;
- pub,可以對外暴露公共接口;
- pub(crate),對整個crate可見;
- pub(in Path),其中Path是模塊路徑,表示可以通過此Path路徑來限定可見范圍;
- pub(self) / pub(in self),只限當前模塊可見;
- pub(super) / pub(in super),當前模塊和父模塊中可見。
Note:trait中關聯(lián)類型和Enum中變體的可見性,會隨著trait和Enum的可見性而變化。但是結構體中的字段需要單獨使用pub來改變可見性。