You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

58 lines
4.7 KiB

## 引用模块树中项目的路径
路径的两种形式:
1. 绝对路径是从 crate 根开始的完整路径;对于来自外部 crate 的代码,绝对路径以 crate 名称开头,对于来自当前 crate 的代码,它从字面量 crate 开始。
2. 相对路径从当前模块开始,并使用 self,super 或当前模块中的标识符。
无论是绝对路径还是相对路径,都要由一个或多个由双冒号(::)分隔的标识符来提示。
![image-20230111101105942](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20230111101105942.png)
选择是使用相对路径还是绝对路径是您将根据您的项目做出的决定,并且取决于您是否更有可能将项目定义代码与使用该项目的代码分开移动或一起移动。例如,如果我们将`front_of_house`模块和`eat_at_restaurant` 函数移动到名为 的模块`customer_experience`中,我们需要将绝对路径更新为`add_to_waitlist`,但相对路径仍然有效。但是,如果我们将`eat_at_restaurant`函数单独移动到名为 的模块`dining`中,调用的绝对路径`add_to_waitlist`将保持不变,但相对路径需要更新。
**我们通常倾向于指定绝对路径,因为我们更有可能希望彼此独立地移动代码定义和项目调用。**
**在 Rust 中,所有项目(函数,方法,结构体,枚举,模块和常量)默认对父模块私有。如果你想让一个像函数或结构体的项目私有,可以把它放在一个模块中。**
### pub关键字
![image-20230111104040810](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20230111104040810.png)
`pub`在前面添加关键字`mod hosting`使模块公开。通过此更改,如果我们可以访问`front_of_house`,我们就可以访问`hosting`。但*内容*`hosting`仍然是私有的;公开模块并不会公开其内容。模块上的`pub`关键字只允许其祖先模块中的代码**引用它**,而不能访问其**内部代码**。因为模块是容器,所以我们只能通过公开模块来做很多事情;我们需要更进一步,选择公开模块中的一项或多项。
### super实现相对路径
我们可以使用 super 在路径开头构建**相对路径**,而不是在当前模块或 crate 根中构建。这类似于使用 **..** 语法开始文件系统路径。使用 super 允许我们引用一个我们知道在父模块中的项目,这可以使重新排列模块树变得更容易,因为当模块与父模块密切相关,但父模块可能会在未来的模块树中移动。
![image-20230111142630499](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20230111142630499.png)
fix_incorrect_order 函数在 back_of_house 模块中,所以我们可以使用 super 去到 back_of_house 的父模块,在这种情况下是根模块 **crate**。然后,我们查找 deliver_order 并找到它。
### 公开结构和枚举
我们还可以使用 pub 来指定结构体和枚举为公共的,但是使用 pub 与结构体和枚举有一些额外的细节。如果在结构体定义前使用 pub,则使结构体公共,但**结构体的字段**仍将是**私有的**。我们可以根据情况分别对每个字段进行公开或不公开。
![image-20230111153714282](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20230111153714282.png)
需要注意的是,由于 back_of_house::Breakfast 具有私有字段,因此该结构体需要提供一个公共关联函数来构造 Breakfast 的实例(我们在这里将其命名为 summer)。如果 Breakfast 没有这样的函数,我们就不能在 eat_at_restaurant 中创建 Breakfast 的实例,因为我们无法在 eat_at_restaurant 中设置私有 seasonal_fruit 字段的值。
![image-20230111163833879](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20230111163833879.png)
#### 公开枚举
如果我们公开一个枚举,那么它的所有变体都是公开的(字段都是公开的)。我们只需要`pub`在`enum`关键字之前。
![image-20230111170619073](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20230111170619073.png)
如果枚举的变量不是公共的,那么它们将没有用处;在每种情况下都要用 pub 注释所有枚举变量将是麻烦的,因此枚举变量的默认值是**公共的**。结构体在没有公共字段的情况下往往很有用,因此结构体字段遵循一般规则,即除非使用 pub 注释,否则一切都是私有的。
在Rust中,结构体或枚举的方法默认都是私有的,不论结构体或枚举是公共的还是私有的。如果你希望让结构体或枚举的方法能被其他代码访问,那么需要在方法前使用 pub 修饰符。