1. 程式人生 > >Rust 中包訪問策略和module開發策略

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: 再見.