在一个crate中,往往是多文件组成的,rust中的多文件,采用mod管理。
同级目录下的mod
假如有以下目录:

其中mod_same_level.rs和main.rs在同一个目录下,mod_same_level.rs中定义了一个函数:
pub fn foo(){ println!("Get called at same level"); }
注意该函数被pub修饰,可以被外部访问到。
在main.rs中的使用方法如下:
mod mod_same_level; use mod_same_level as msl; use mod_same_level::foo; use mod_same_level::foo as poo; fn main() { // use mod at the same level mod_same_level::foo(); msl::foo(); foo(); poo(); }
代码中四种调用函数的结果都是一样的,注意的点为:
- 先用mod mod_same_level引入mod_same_level.rs文件,类似于import
- 可以直接使用mod_same_level::foo()的方式调用,也可以结合use的方式使用。use一般用于起别名,或者减少代码中的前缀,比如use mod_same_level::foo,就可以直接在代码中调用foo(),而不用写一长串mod_same_level::foo()
子目录下的mod
假设我们有一个mod目录如下:

·其中inner_mod_private.rs中的函数没有定义为pub,则为private:
fn inner_foo(){ println!("Get called at inner mod private"); }
代表着只能在inner_mod_prviate.rs文件中访问。其他任何地方的文件都不能被访问到,包括mod_folder/mod.rs,因此这种没有被pub修饰的函数,不可能作为导出接口。
而inner_mod_public.rs中的函数定义为pub,则可以被外部其他文件访问:
pub fn inner_foo(){ println!("Get called at inner mod public"); } pub fn inner_poo(){ println!("Get called at inner mod public"); }
但实际开发时,往往会通过mod_folder/mod.rs文件再次统一封装的对外接口,把所有作用域为pub的接口进行管理。比如:
- 导出整个子mod。
在mod.rs中这样写,意味着导出inner_mod_public.rs文件中所有pub函数:
pub mod inner_mod_public;
则在main.rs这样调用时正确的:
mod mod_folder; fn main() { mod_folder::inner_mod_public::inner_foo(); mod_folder::inner_mod_public::inner_poo(); }
- 导出子mod中部分pub函数
也可以导出指定的函数,比如mod.rs中这样写:
mod inner_mod_public; pub use inner_mod_public::inner_foo;
第一行把inner_mod_public作用域设置为private,第二行把inner_foo函数设置为pub,因此在main.rs中只能访问inner_foo,不能访问inner_poo:
mod mod_folder; fn main() { mod_folder::inner_foo(); }
使用任意目录的mod
假如有以下目录:

sub_mod_folder_a/mod.rs中,想调用sub_mod_folder_b中的函数怎么办呢?
使用mod路径来调用,这样写:
use crate::mod_folder::sub_mod_folder_b; pub fn foo(){ sub_mod_folder_b::foo(); }
这里的crate::mod_folder::sub_mod_folder_b就是mod路径。crate指的就是bin或者lib的入口。要注意这里用的是use关键字,而不是mod,说明mod已经被包含进crate中了。因此,这样写的前提就是:
- mod_folder已经被main.rs引入了,也就是在main.rs中,有这样的代码:
mod mod_folder;
- sub_mod_folder_b已经被mod_folder引入了,在mod_folder/mod.rs中,有这样的代码:
pub mod sub_mod_folder_b;
以此类推,只要任意一个mod被引入进了crate中,就可以通过crate::any_mod这样的路径被使用。
pub可见性
首先要明确一点,不设置pub的时候,则该成员为private,private对本mod都可见,对外都不可见。
然后可以通过pub关键字,设置pub成员对指定的mod可见,比如:
// 对外部所有模块可见 pub fn function() { println!("called `my_mod::nested::function()`"); } // 使用 `pub(in path)` 语法定义的函数只在给定的路径中可见。 // `path` 必须是父模块(parent module)或祖先模块(ancestor module) pub(in crate::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)` 语法定义的函数则只在当前模块中可见。 pub(self) fn public_function_in_nested() { println!("called `my_mod::nested::public_function_in_nested"); } // 使用 `pub(super)` 语法定义的函数只在父模块中可见。 pub(super) fn public_function_in_super_mod() { println!("called my_mod::nested::public_function_in_super_mod"); }
虽然pub(self)和private都对外不可见,但二者也有区别:
- pub(self)对子模块可见
- private对子模块不可见
发表回复