模块(Rust入门)
本文章参考自官方学习文档及社区学习文档以下是参考链接:
官方:
社区:
直接上手学习推荐:
概述点
Rust 提供了一套强大的模块(module)系统,可以将代码按层次分成多个逻辑单元,并管理这些模块之间的可见性(公有(public)或私有(private))。
模块是项(item)的集合,项可是是:函数,结构体,trait
,impl
块,甚至其他模块
本文内容:
- 模块中的项的可见性
- 结构体的可见性
use
声明
super
和 self
- 文件分层
可见性
默认情况下,模块中的项拥有私有的可见性(private visibility),不过可以加上 pub
修饰语来重载这一行为。模块中只有公有的(public)项可以从模块外的作用域访问
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| mod my_mod { fn private_function() { println!("called `my_mod::private_function()`"); }
pub fn function() { println!("called `my_mod::function()`"); }
pub fn indirect_access() { print!("called `my_mod::indirect_access()`, that\n> "); private_function(); }
pub mod nested { pub fn function() { println!("called `my_mod::nested::function()`"); }
#[allow(dead_code)] fn private_function() { println!("called `my_mod::nested::private_function()`"); }
pub(in my_mod) fn public_function_in_my_mod() { print!("called `my_mod::nested::public_function_in_my_mod()`, that\n > "); public_function_in_nested() }
pub(self) fn public_function_in_nested() { println!("called `my_mod::nested::public_function_in_nested"); }
pub(super) fn public_function_in_super_mod() { println!("called my_mod::nested::public_function_in_super_mod"); } }
pub fn call_public_function_in_my_mod() { print!("called `my_mod::call_public_funcion_in_my_mod()`, that\n> "); nested::public_function_in_my_mod(); print!("> "); nested::public_function_in_super_mod(); }
pub(crate) fn public_function_in_crate() { println!("called `my_mod::public_function_in_crate()"); }
mod private_nested { #[allow(dead_code)] pub fn function() { println!("called `my_mod::private_nested::function()`"); } } }
fn function() { println!("called `function()`"); }
fn main() { function(); my_mod::function();
my_mod::indirect_access(); my_mod::nested::function(); my_mod::call_public_function_in_my_mod();
my_mod::public_function_in_crate();
}
|
结构体的可见性
结构体的字段也是一个可见性的层次。字段默认拥有私有的可见性,也可以加上 pub
修饰语来重载该行为。只有从结构体被定义的模块之外访问其字段时,这个可见性才会起作用,其意义是隐藏信息(即封装,encapsulation)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| mod my { pub struct OpenBox<T> { pub contents: T, }
#[allow(dead_code)] pub struct ClosedBox<T> { contents: T, }
impl<T> ClosedBox<T> { pub fn new(contents: T) -> ClosedBox<T> { ClosedBox { contents: contents, } } }
impl <T: std::fmt::Display> std::fmt::Display for ClosedBox<T> { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "The closed box contains: {}", self.contents) } } }
fn main() { let open_box = my::OpenBox { contents: "public information" };
println!("The open box contains: {}", open_box.contents);
let _closed_box = my::ClosedBox::new("classified information");
println!("{}", _closed_box); }
|
use 声明
use
声明可以将一个完整的路径绑定到一个新的名字,从而更容易访问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| use deeply::nested::function as other_function;
fn function() { println!("called `function()`"); }
mod deeply { pub mod nested { pub fn function() { println!("called `deeply::nested::function()`") } } }
fn main() { other_function();
println!("Entering block"); { use deeply::nested::function; function();
println!("Leaving block"); }
function(); }
|
super 和 self
可以在路径中使用 super
(父级) 和 self
(自身)关键字,从而在访问项时消除歧义,以及防止不必要的路径硬编码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| fn function() { println!("called `function()`"); }
mod cool { pub fn function() { println!("called `cool::function()`"); } }
mod my { fn function() { println!("called `my::function()`"); }
mod cool { pub fn function() { println!("called `my::cool::function()`"); } }
pub fn indirect_call() { print!("called `my::indirect_call()`, that\n> ");
self::function(); function();
self::cool::function();
super::function();
{ use cool::function as root_function; root_function(); } } }
fn main() { my::indirect_call(); }
|
文件分层
模块可以分配到文件/目录的层次结构中。让我们将 可见性 的代码拆分到多个文件中:
1 2 3 4 5 6 7
| $ tree . . |-- my | |-- inaccessible.rs | |-- mod.rs | `-- nested.rs `-- split.rs
|
split.rs
的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
mod my;
fn function() { println!("called `function()`"); }
fn main() { my::function();
function();
my::indirect_access();
my::nested::function(); }
|
my/mod.rs
的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
mod inaccessible; pub mod nested;
pub fn function() { println!("called `my::function()`"); }
fn private_function() { println!("called `my::private_function()`"); }
pub fn indirect_access() { print!("called `my::indirect_access()`, that\n> ");
private_function(); }
|
my/nested.rs
的内容:
1 2 3 4 5 6 7 8
| pub fn function() { println!("called `my::nested::function()`"); }
#[allow(dead_code)] fn private_function() { println!("called `my::nested::private_function()`"); }
|
my/inaccessible.rs
的内容:
1 2 3 4
| #[allow(dead_code)] pub fn public_function() { println!("called `my::inaccessible::public_function()`"); }
|
1 2
| rustc split.rs && ./split
|