Rust 提供了代码封装的机制。可以通过crate (等同于Java中的package)创建相对独立的module模块,模块中封装了可以重复使用的功能函数。
当创建了自己的 lib 库或者要使用第三方的库的时候(这些库就是一些事先写好的crate)需要将这些库中的module 模块引用到当前的环境中。
Rust提供了以下几种引用方式:
在使用这些Module的文件中,通过 extern crate + crate名称将包内的模块引入当前环境。
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());
}
通过 extern crate 引入的 crate 或者类库,需要通过两个 :: 双引号逐层将需要引用的module模块,直到调用的功能函数为止,比如:
my_library::english::farewells::goodbye()
这里说一下上面这一行都是什么?什么关系?
二、crate、module和功能方法的关系
my_library::english::farewells::goodbye()
my_library 是我们使用 cargo new 创建的项目名称,也就是项目默认的module的名字,这个module是 root module,module对应的文件是 lib.rs 。
所以,当我们在 lib.rs 中声明 pub mod english;
的时候,就产生了这样的关系 my_library::english
;
然后在 src/english.rs 或者 src/english/mod.rs 中声明 pub mod farewells;
时,就有这样的关系my_library::english::farewells
最后,到达声明的方法为止。
my_library::english::farewells::goodbye()
这也叫做从root module (根模块) my_library 到功能函数 goodbye的绝对路径。
在使用 extern 引入包之后,可以用 use 将模块引入到当前作用域。
extern crate my_library;
use my_library::english::greetings::hello;
use my_library::english::farewells::goodbye;
fn main() {
println!("Hello in English: {}", hello());
println!("Goodbye in English: {}", goodbye());
}
这样,就可以像使用本地功能函数一样使用模块中的功能函数了。
引入同一个模块中的功能函数,这么多模块重复写,太不方便了!
use my_library::english::greetings::hello;
use my_library::english::farewells::goodbye;
可以用{}简写这样:
use my_library::english::{greetings, farewells};
在 src/english/mod.rs中,定义了两个模块 greetings 和 farewells 。
pub mod greetings;
pub mod farewells;
通过 use 可以使用上面的绝对路径引用功能函数。
my_library::english::greetings::hello()
修改如下:
pub use self::greetings::hello;
pub use self::farewells::goodbye;
mod greetings;
mod farewells;
pub use 将后面的跟随的模块中的功能函数引入当前作用域。
使用的时候,
extern crate my_library;
use my_library::english::hello;
use my_library::english::goodbye;
fn main() {
println!("Hello in English: {}", hello());
println!("Goodbye in English: {}", goodbye());
}
还可以用 * ,把greetings的所有内容引入当前模块作用域。
pub use self::greetings::*;
mod greetings;
mod farewells;
self 是什么? self 指的是当前模块,这里的self指的是 english 模块。除了 self ,还有 super 指向当前模块的上级模块。
self 和 super 都是相对路径。
extern crate my_library as sayings;
use sayings::chinese::greetings as ch_greetings;
use sayings::chinese::farewells::*;
use sayings::english::{self, greetings as en_greetings, farewells as en_farewells};
fn main() {
println!("Hello in English; {}", en_greetings::hello());
println!("And in Chinese: {}", ch_greetings::hello());
println!("Goodbye in English: {}", english::farewells::goodbye());
println!("Again: {}", en_farewells::goodbye());
println!("And in Chinese: {}", goodbye());
}
上面的代码除了第四句,其他的都好理解。
第四句等同于:
use sayings::english;
use sayings::english::greetings as en_greetings;
use sayings::english::farewells as en_farewells;