定义模块以控制作用域和隐私

RustRustBeginner
立即练习

This tutorial is from open-source community. Access the source code

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

欢迎来到「定义模块以控制作用域和隐私」实验。本实验是 《Rust 程序设计语言》 的一部分。你可以在 LabEx 中练习 Rust 技能。

在本实验中,我们将学习模块以及它们如何让我们在一个包(crate)中组织代码、控制项的隐私,并提供一种在模块树中导航的方法。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") subgraph Lab Skills rust/function_syntax -.-> lab-100402{{"定义模块以控制作用域和隐私"}} end

定义模块以控制作用域和隐私

在本节中,我们将讨论模块以及模块系统的其他部分,即 路径,它允许你为项命名;use 关键字,用于将路径引入作用域;以及 pub 关键字,用于使项公开。我们还将讨论 as 关键字、外部包和通配符运算符。

模块 使我们能够在一个包(crate)中组织代码,以提高可读性并便于重用。模块还允许我们控制项的 隐私性,因为模块内的代码默认是私有的。私有项是内部实现细节,外部不可用。我们可以选择将模块及其内部的项设为公共的,这样它们就可供外部代码使用和依赖。

例如,让我们编写一个库包(crate),提供餐厅的功能。我们将定义函数的签名,但将函数体留空,以便专注于代码的组织,而不是餐厅功能的实现。

在餐饮行业中,餐厅的某些部分被称为 前台,其他部分被称为 后台。前台是顾客所在的地方,包括接待员安排顾客就座、服务员接单和收款以及调酒师调制饮品的地方。后台是厨师和帮厨在厨房工作、洗碗工清理以及经理进行行政工作的地方。

为了以这种方式构建我们的包(crate),我们可以将其函数组织成嵌套模块。通过运行 cargo new restaurant --lib 创建一个名为 restaurant 的新库。然后将清单 7-1 中的代码输入到 src/lib.rs 中,以定义一些模块和函数签名;这段代码是前台部分。

文件名:src/lib.rs

mod front_of_house {
    mod hosting {
        fn add_to_waitlist() {}

        fn seat_at_table() {}
    }

    mod serving {
        fn take_order() {}

        fn serve_order() {}

        fn take_payment() {}
    }
}

清单 7-1:一个包含其他模块的 front_of_house 模块,这些模块又包含函数

我们使用 mod 关键字后跟模块名称(在本例中为 front_of_house)来定义一个模块。然后模块体放在花括号内。在模块内部,我们可以放置其他模块,就像本例中的 hostingserving 模块一样。模块还可以包含其他项的定义,例如结构体、枚举、常量、trait,以及 —— 如清单 7-1 所示 —— 函数。

通过使用模块,我们可以将相关定义分组在一起,并说明它们相关的原因。使用此代码的程序员可以根据这些组来浏览代码,而不必通读所有定义,从而更容易找到与他们相关的定义。为这段代码添加新功能的程序员会知道将代码放在哪里以保持程序的组织性。

之前,我们提到 src/main.rssrc/lib.rs 被称为包根(crate roots)。它们得名的原因是这两个文件中的任何一个的内容在包的模块结构的根处形成一个名为 crate 的模块,称为 模块树

清单 7-2 展示了清单 7-1 中结构的模块树。

crate
└── front_of_house
├── hosting
│ ├── add_to_waitlist
│ └── seat_at_table
└── serving
├── take_order
├── serve_order
└── take_payment

清单 7-2:清单 7-1 中代码的模块树

此树展示了一些模块如何嵌套在其他模块中;例如,hosting 嵌套在 front_of_house 中。该树还显示一些模块是 同级模块,这意味着它们在同一个模块中定义;hostingserving 是在 front_of_house 中定义的同级模块。如果模块 A 包含在模块 B 中,我们说模块 A 是模块 B 的 子模块,模块 B 是模块 A 的 父模块。请注意,整个模块树以名为 crate 的隐式模块为根。

模块树可能会让你想起计算机上文件系统的目录树;这是一个非常恰当的类比!就像文件系统中的目录一样,你使用模块来组织代码。就像目录中的文件一样,我们需要一种方法来找到我们的模块。

总结

恭喜你!你已经完成了「定义模块以控制作用域和隐私」实验。你可以在 LabEx 中练习更多实验来提升你的技能。