跳到主要内容

Rust模块

提示
  1. 模块定义和结构:在 Rust 中,使用 mod 关键字定义模块,它帮助组织代码为逻辑单元,提高可读性。一个模块可以包含函数、结构体,甚至是其他模块。
  2. 模块项的可见性:模块内的项默认为私有,但可以使用 pub 关键字来公开。公共项在模块外部可访问,而私有项只能在模块内部使用。
  3. 使用和嵌套模块:可以通过 use 关键字将模块项引入当前作用域,简化代码。模块可以嵌套,允许创建分层和组织良好的代码结构。

Rust 中的模块有助于将程序分割为逻辑单元,以提高可读性和组织性。

一旦程序变得更大,将其分割为多个文件或命名空间变得非常重要。模块有助于构建我们的程序结构。

一个模块是一个包含函数、结构体甚至是其他模块的集合。

在 Rust 中定义模块

使用 mod 关键字来定义模块。模块的语法是:

// 模块的语法
mod module_name {
// 代码
}

这里,module_name 是模块的名称。

现在,让我们定义一个模块。

// 一个名为 config 的模块
mod config {
// 模块内的 print 函数
fn print() {
println!("config!");
}
}

在上述示例中,我们使用 mod 关键字创建了一个名为 config 的模块。

在模块内部,我们可以定义多个项。这里,我们定义了 print() 函数。

Rust 中模块内项的可见性

模块内的项可以是私有的或公共的。默认情况下,模块是私有的。这意味着模块内的项无法在模块外部访问。

可以使用 pub 关键字来赋予项公共可见性。

让我们看一个例子。

mod config {
// 模块内的项默认是私有的
fn select() {
println!("called config::select");
}

// 使用 `pub` 关键字来覆盖私有可见性
pub fn print() {
println!("called config::print");
}
}

这里,我们定义了一个名为 config 的模块,其中包含两个函数 select()print()

print() 函数以 pub 关键字开头,意味着它具有公共可见性。然而,select() 函数则没有。

如果我们编译上述程序,我们不会得到任何输出,因为我们还没有使用这些函数。

warning: function `select` is never used
--> src/lib.rs:3:8
|
3 | fn select() {
| ^^^^^^
|
= note: `#[warn(dead_code)]` on by default

warning: function `print` is never used
--> src/lib.rs:8:12
|
8 | pub fn print() {
| ^^^^^

现在,让我们调用模块内的函数。

mod config {
// 模块内的项默认是私有的
fn select() {
println!("called config::select");
}

// 使用 `pub` 关键字来覆盖私有可见性
pub fn print() {
println!("called config::print");
}
}

fn main() {
// 模块内的公共项可以在父模块外部访问
// 从 display 模块调用公共 print 函数
config::print();
}

输出

called display::print

这里,我们使用 config::print() 语法调用 config 模块内的公共函数 print():: 运算符用于分隔模块名称和要在模块内调用的项。

然而,模块内的私有项无法在模块外部访问。如果我们调用 config 模块内的私有函数 select(),我们会得到一个编译错误。

mod config {
// 模块内的项默认是私有的
fn select() {
println!("called config::select");
}

// 使用 `pub` 关键字来覆盖私有可见性
pub fn print() {
println!("called config::print");
}
}

fn main() {
// 模块内的私有项不能在父模块外部

访问
// 调用 config 模块内的私有 select 函数将导致编译错误
display::select();
}

错误

error[E0603]: function `select` is private
--> src/main.rs:16:14
|
16 | display::select();
| ^^^^^^ private function

这个错误表明 function select is private。因此,在模块内部项目的可见性是一个重要的设计考虑。

注意: 当与 pub 关键字一起使用时,模块也可以具有公共可见性。

示例:在 Rust 中使用模块

mod player {
// 私有函数
fn focus() {
println!("called player::focus");
}

// 公共函数
pub fn shift() {
println!("called player::shift");
}

// 公共函数
pub fn jump() {
// 在模块内部调用私有函数 focus 和 shift
focus();
shift();
println!("called player::jump");
}
}

fn main() {
// 从 player 模块调用公共函数 jump
player::jump();
}

输出

called player::focus
called player::shift
called player::jump

这里,我们在 player 模块内定义了多个函数。注意我们可以在同一模块内的另一个函数 jump() 中调用私有函数 focus()

嵌套模块

一个模块可以定义在另一个模块内部。这被称为模块嵌套。

让我们看一个例子。

// 嵌套模块
pub mod player {
pub mod sprite {
pub fn create() {
println!("called player::sprite::create");
}
}
}

fn main() {
// 从 player 模块内的 sprite 模块调用公共函数 create
player::sprite::create();
}

输出

called player::sprite::create

这里,我们有一个 sprite 模块嵌套在 player 模块内。

我们在 sprite 模块内定义了一个公共函数 create(),在模块外部的 main() 函数中通过 player::sprite::create() 调用它。

Rust 中的 use 关键字

我们可以使用 use 关键字将模块内的项目引入当前作用域。use 关键字帮助我们避免写出完整的模块路径来调用函数。

让我们用 use 关键字重写我们的嵌套模块示例。

// 嵌套模块
pub mod player {
pub mod sprite {
pub fn create() {
println!("called player::sprite::create");
}
}
}

// 将 create 函数引入作用域
use player::sprite::create;

fn main() {
// 直接调用公共函数
create();
}

输出

called player::sprite::create

这里,我们使用 use 关键字将 sprite 模块内的 create() 函数引入当前作用域。这使我们能够直接调用 create() 函数,而不必将其名称完全限定为 player::sprite::create()