mirror of
https://github.com/KaiserY/trpl-zh-cn
synced 2024-11-13 03:21:20 +08:00
update: 添加新版ch07-03第二部分的翻译
This commit is contained in:
parent
93f26c177c
commit
d98eb5d71b
@ -70,3 +70,82 @@ error[E0603]: module `hosting` is private
|
||||
Rust中默认所有项(函数、方法、结构体、枚举、模块和常量)都是私有的。父模块中的项不能使用子模块中的私有项,但是子模块中的项可以使用他们父模块中的项。这是因为子模块封装并隐藏了他们的实现详情,但是子模块可以看到他们定义的上下文。继续拿餐馆作比喻,把私有性规则想象成餐馆的后台办公室:餐馆内的事务对餐厅顾客来说是不可知的,但办公室经理可以洞悉其经营的餐厅并在其中做任何事情。
|
||||
|
||||
Rust 选择以这种方式来实现模块系统功能,因此默认隐藏内部实现细节。这样一来,你您就知道可以更改内部代码的哪些部分而不会破坏外部代码。你还可以通过使用`pub`关键字来创建公共项,使子模块的内部部分暴露给上级模块。
|
||||
|
||||
## 使用`pub`关键字暴露路径
|
||||
|
||||
让我们回头看一下示例 7-4 的错误,它告诉我们`hosting`模块是私有的。我们想让父模块中的`eat_at_restaurant`函数可以访问子模块中的`add_to_waitlist`函数,因此我们使用`pub`关键字来标记`hosting`模块,如示例 7-5 所示。
|
||||
|
||||
<span class="filename">文件名: src/lib.rs</span>
|
||||
|
||||
```rust,ignore,does_not_compile
|
||||
mod front_of_house {
|
||||
pub mod hosting {
|
||||
fn add_to_waitlist() {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eat_at_restaurant() {
|
||||
// Absolute path
|
||||
crate::front_of_house::hosting::add_to_waitlist();
|
||||
|
||||
// Relative path
|
||||
front_of_house::hosting::add_to_waitlist();
|
||||
}
|
||||
```
|
||||
|
||||
<span class="caption">示例 7-5: 使用 `pub` 关键字声明 `hosting` 模块使其可在 `eat_at_restaurant` 使用</span>
|
||||
|
||||
不幸的是,示例 7-5 的代码编译仍然有错误,如示例 7-6 所示。
|
||||
|
||||
```text
|
||||
$ cargo build
|
||||
Compiling restaurant v0.1.0 (file:///projects/restaurant)
|
||||
error[E0603]: function `add_to_waitlist` is private
|
||||
--> src/lib.rs:9:37
|
||||
|
|
||||
9 | crate::front_of_house::hosting::add_to_waitlist();
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0603]: function `add_to_waitlist` is private
|
||||
--> src/lib.rs:12:30
|
||||
|
|
||||
12 | front_of_house::hosting::add_to_waitlist();
|
||||
| ^^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
<span class="caption">示例 7-6: 构建示例 7-5 出现的编译器错误</span>
|
||||
|
||||
发生了什么?在`mod hosting`前添加了`pub`关键字,使其变成公有的。伴随着这种变化,如果我们可以访问`front_of_house`,那我们也可以访问`hosting`。但是`hosting`的*内容*(*contents*)仍然是私有的;这表明使模块公有并不使其内容也是公有的。模块上的 `pub` 关键字只允许其父模块引用它。
|
||||
|
||||
示例 7-6 中的错误说,`add_to_waitlist`函数是私有的。私有性规则不但应用于模块,还应用于结构体、枚举、函数和方法。
|
||||
|
||||
让我们继续将`pub`关键字放置在`add_to_waitlist`函数的定义之前,使其变成公有。如示例 7-7 所示。
|
||||
|
||||
<span class="filename">文件名: src/lib.rs</span>
|
||||
|
||||
```rust
|
||||
mod front_of_house {
|
||||
pub mod hosting {
|
||||
pub fn add_to_waitlist() {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eat_at_restaurant() {
|
||||
// Absolute path
|
||||
crate::front_of_house::hosting::add_to_waitlist();
|
||||
|
||||
// Relative path
|
||||
front_of_house::hosting::add_to_waitlist();
|
||||
}
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
<span class="caption">示例 7-7: 为 `mod hosting`
|
||||
和 `fn add_to_waitlist` 添加 `pub` 关键字使他们可以在
|
||||
`eat_at_restaurant`函数中被调用</span>
|
||||
|
||||
现在代码可以编译通过了!让我们看看绝对路径和相对路径,并根据私有性规则,再检查一下为什么增加 `pub` 关键字使得我们可以在 `add_to_waitlist` 中调用这些路径。
|
||||
|
||||
在绝对路径,我们从 `crate`,也就是 crate 根开始。然后 crate 根中定义了 `front_of_house` 模块。`front_of_house` 模块不是公有的,不过因为 `eat_at_restaurant` 函数与 `front_of_house` 定义于同一模块中(即,`eat_at_restaurant`和`front_of_house`是兄弟),我们可以从 `eat_at_restaurant` 中引用 `front_of_house`。接下来是使用 `pub` 标记的 `hosting` 模块。我们可以访问 `hosting` 的父模块,所以可以访问 `hosting`。最后,`add_to_waitlist` 函数被标记为 `pub` ,我们可以访问其父模块,所以这个函数调用是有效的!
|
||||
|
||||
在相对路径,其逻辑与绝对路径相同,除了第一步:不同于从 crate 根开始,路径从 `front_of_house` 开始。`front_of_house` 模块与 `eat_at_restaurant` 定义于同一模块,所以从 `eat_at_restaurant` 中开始定义的该模块相对路径是有效的。接下来因为 `hosting` 和 `add_to_waitlist` 被标记为 `pub`,路径其余的部分也是有效的,因此函数调用也是有效的!
|
||||
|
Loading…
Reference in New Issue
Block a user