Rust 中包訪問策略和module開發策略
一、建立新專案
$cargo new my_library
當前路徑下包含 Cargo.toml 和 src 目錄;
src 目錄下包含一個 lib.rs 檔案。
二、不使用module的情況
1、修改lib程式碼
$vi src/lib.rs
修改程式碼如下:
pub fn public_function() { println!(" my library's `public_function()` called"); } fn private_function() { println!(" my library's `private_function()` called"); } pub fn indirect_access() { print!("my library's `indirect_access()` called "); private_function(); }
Rust 中所有的功能函式預設都是私有的 private,只允許同一個檔案內的功能函式訪問。為了能讓其他包中的功能函式訪問,必須在 fn 前面宣告 pub 。
2、建立呼叫檔案
$vi src/main.rs
檔案內容如下:
extern crate my_library;
fn main() {
my_library::public_function();
my_library::indirect_access();
}
程式碼中 my_library 是我們前面建立的專案名稱,也叫 crate 。
extern crate 連結 my_library,在當前檔案內可以使用 my_library訪問的功能函式。
lib.rs 是 Rust 建立的預設的module,module的名字就是專案的名字或者叫做 crate的名字:my_library。
因此,在呼叫的時候,需要使用 my_library加上兩個 : 冒號,來呼叫功能函式。
$cargo run
$ cargo run
Compiling my_library v0.1.0 (file:///Users/teamlet/develop/rust-projects/my_library)
Running `target/debug/my_library`
my library's `public_function()` called
my library's `indirect_access()` called my library's `private_function()` called
三、使用單檔案module
1、修改lib程式碼
vi src/lib.rs
pub mod english {
pub mod greetings {
pub fn hello() -> String {
"Hello!".to_string()
}
}
pub mod farewells {
pub fn goodbye() -> String {
"Goodbye.".to_string()
}
}
}
pub mod chinese {
pub mod greetings {
pub fn hello() -> String {
"你好!".to_string()
}
}
pub mod farewells {
pub fn goodbye() -> String {
"再見.".to_string()
}
}
}
上面程式碼中,english和chinese是 root module 根模組的的兩個子模組,root module 的名字是 my_library!
每個子模組下面又包含兩個子模組 greetings 和farewells 。
因為要在模組外部訪問功能方法,所以所有的module和功能函式都要宣告為 pub 即:public屬性。
2、建立呼叫檔案
$vi src/main.rs
extern crate my_library;
fn main() {
println!("Hello in English: {}",my_library::english::greetings::hello());
println!("Goodbye in English: {}", my_library::english::farewells::goodbye());
println!("Hello in Chinese: {}", my_library::chinese::greetings::hello());
println!("Goodbye in Chinese: {}", my_library::chinese::farewells::goodbye());
}
執行
$cargo run
$ cargo run
Running `target/debug/my_library`
Hello in English: Hello!
Goodbye in English: Goodbye.
Hello in Chinese: 你好!
Goodbye in Chinese: 再見.
在呼叫程式碼中,功能函式通過 :: 從root module (這裡是 my_library)一層一層的訪問子模組直到最後的功能函式。
四、使用多檔案module
從上面的程式碼可以看出,一個 crate 就是一個 rs 檔案。
在rs檔案中,通過mod和 { } 把root module 下的子模組規劃出來。
mod 可以包含任意個子模組。
當一個檔案中的mod數量太多,也會出現閱讀、修改、管理的問題。
Rust提供機制,可以將 mod 分別儲存在不同的檔案中。
1、修改lib程式碼
$vi src/lib.rs
pub mod english;
pub mod chinese;
Rust會查詢 src/english.rs 或者 src/english/mod.rs
同樣,也會查詢 src/chinese.rs 或者 src/chinese/mod.rs
因為還有第三層的module,所以選擇後面一種方式。
建立 src/english/mod.rs 和 src/chinese/mod.rs
$mkdir src/english
$vi src/english/mod.rs
內容如下:
pub mod greetings;
pub mod farewells;
$mkdir src/chinese
$vi src/chinese/mod.rs
內容如下:
pub mod greetings;
pub mod farewells;
這是,Rust會分別在english目錄和chinese目錄下查詢greetings.rs或者 greetings/mod.rs ,也會同樣查詢 farewells.rs 或者 farewells/mod.rs 。
因為這兩個mod不再包含子模組,所以採用greetings.rs和farewells.rs 的方式。
$vi src/english/greetings.rs
內容如下:
pub fn hello() -> String {
"Hello!".to_string()
}
$vi src/english/farewell.rs
內容如下:
pub fn goodbye() -> String {
"Goodbye.".to_string()
}
$vi src/chinese/greetings.rs
內容如下:
pub fn hello() -> String {
"你好!".to_string()
}
$vi src/chinese/farewells.rs
內容如下:
pub fn goodbye() -> String {
"再見.".to_string()
}
2、呼叫程式碼不變,如下
extern crate my_library;
fn main() {
println!("Hello in English: {}", my_library::english::greetings::hello());
println!("Goodbye in English: {}", my_library::english::farewells::goodbye());
println!("Hello in Chinese: {}", my_library::chinese::greetings::hello());
println!("Goodbye in Chinese: {}", my_library::chinese::farewells::goodbye());
}
執行
$cargo run
cargo run
Compiling my_library v0.1.0 (file:///Users/teamlet/develop/rust-projects/my_library)
Running `target/debug/my_library`
Hello in English: Hello!
Goodbye in English: Goodbye.
Hello in Chinese: 你好!
Goodbye in Chinese: 再見.