|
|
|
@ -0,0 +1,61 @@
|
|
|
|
|
# 定义模块来控制作用域与私有性
|
|
|
|
|
|
|
|
|
|
> [ch07-02-defining-modules-to-control-scope-and-privacy.md](https://github.com/rust-lang/book/blob/master/src/ch07-02-defining-modules-to-control-scope-and-privacy.md)
|
|
|
|
|
> <br>
|
|
|
|
|
> commit 879fef2345bf32751a83a9e779e0cb84e79b6d3d
|
|
|
|
|
|
|
|
|
|
在本节,我们将讨论模块和其它一些关于模块系统的部分,如允许你命名项的*路径*(*paths*);用来将路径引入作用域的`use`关键字;以及使项变为公有的`pub`关键字。我们还将讨论`as`关键字、外部包和 glob 运算符。现在,让我们把注意力放在模块上!
|
|
|
|
|
|
|
|
|
|
*模块*让我们可以将一个 crate 中的代码进行分组,以提高可读性与重用性。模块还可以控制项的*私有性*,即项是可以被外部代码使用的(*public*),还是作为一个内部实现的内容,不能呢个为外部代码使用(*private*)。
|
|
|
|
|
|
|
|
|
|
在餐饮业,餐馆中会有一些地方被称之为*前台*(*front of house*),还有另外一些地方被称之为*后台*(*back of house*)。前台是招待顾客的地方,在这里,店主可以为顾客安排座位,服务员接受顾客下单和付款,调酒师会制作饮品。后台则是由厨师工作的厨房,洗碗工的工作地点,以及经理做行政工作的地方组成。
|
|
|
|
|
|
|
|
|
|
我们可以将函数放置到嵌套的模块中,来使我们的 crate 结构与实际的餐厅结构相同。通过执行`cargo new --lin restaurant`,来创建一个新的名为`restaurant`的库。然后将示例 7-1中所罗列出来的代码放入*src/lib.rs*中,来定义一些模块和函数。
|
|
|
|
|
|
|
|
|
|
Filename: src/lib.rs
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
mod front_of_house {
|
|
|
|
|
mod hosting {
|
|
|
|
|
fn add_to_waitlist() {}
|
|
|
|
|
|
|
|
|
|
fn seat_at_table() {}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mod serving {
|
|
|
|
|
fn take_order() {}
|
|
|
|
|
|
|
|
|
|
fn server_order() {}
|
|
|
|
|
|
|
|
|
|
fn take_payment() {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
<span class="caption">示例 7-1:一个包含了其他内置了函数的模块的`front_of_house`模块</span>
|
|
|
|
|
|
|
|
|
|
我们定义一个模块,是以`mod`关键字为起始,然后指定模块的名字(本例中叫做`front_of_house`),并且用花括号包围模块的主体。在模块内,我们还可以定义其他的模块,就像本例中的`hosting`和`serving`模块。模块还可以保存一些定义的其他项,比如结构体、枚举、常量、特性、或者函数。
|
|
|
|
|
|
|
|
|
|
通过使用模块,我们可以将相关的定义分组到一起,并指出他们为什么相关。程序员可以通过使用这段代码,更加容易地找到他们想要的定义,因为他们可以基于分组来对代码进行导航,而不需要阅读所有的定义。程序员向这段代码中添加一个新的功能时,他们也会知道代码应该放置在何处,可以保持程序的组织性。
|
|
|
|
|
|
|
|
|
|
在前面我们提到了,`src/main.rs`和`src/lib.rs`叫做 crate 根。之所以这样叫它们的原因是,这两个文件的内容都是一个从名为`crate`的模块作为根的 crate 模块结构,称为*模块树*(*module tree*)。
|
|
|
|
|
|
|
|
|
|
示例 7-2 展示了示例 7-1 中的模块树的结构。
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
crate
|
|
|
|
|
└── front_of_house
|
|
|
|
|
├── hosting
|
|
|
|
|
│ ├── add_to_waitlist
|
|
|
|
|
│ └── seat_at_table
|
|
|
|
|
└── serving
|
|
|
|
|
├── take_order
|
|
|
|
|
├── serve_order
|
|
|
|
|
└── take_payment
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
<span class="caption">示例 7-2: 示例 7-1 中代码的模块树</span>
|
|
|
|
|
|
|
|
|
|
这个树展示了一些模块是如何被嵌入到另一个模块的(例如,`hosting`嵌套在`front_of_house`中)。这个树还展示了一些模块是互为*兄弟*(*siblings*)的,这意味着它们定义在同一模块中(`hosting`和`serving`被一起定义在`front_of_house`中)。继续沿用家庭关系的比喻,如果一个模块 A 被包含在模块 B 中,我们将模块 A 称为模块 B 的*子*(*child*),模块 B 则是模块 A 的*父*(*parent*)。注意,整个模块树都植根于名为`crate`的隐式模块下。
|
|
|
|
|
|
|
|
|
|
这个模块树可能会令你想起电脑上文件系统的目录树;这是一个非常恰当的比喻!就像文件系统的目录,你可以使用模块来组织你的代码。并且,就像目录中的文件,我们需要一种方法来找到模块。
|