🎃个人专栏:
🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客
🐳Java基础:Java基础_IT闫的博客-CSDN博客
🐋c语言:c语言_IT闫的博客-CSDN博客
🐟MySQL:数据结构_IT闫的博客-CSDN博客
🐠数据结构:数据结构_IT闫的博客-CSDN博客
💎C++:C++_IT闫的博客-CSDN博客
🥽C51单片机:C51单片机(STC89C516)_IT闫的博客-CSDN博客
💻基于HTML5的网页设计及应用:基于HTML5的网页设计及应用_IT闫的博客-CSDN博客
🥏python:python_IT闫的博客-CSDN博客
🐠离散数学:离散数学_IT闫的博客-CSDN博客
🥽Linux:Linux_Y小夜的博客-CSDN博客
🚝Rust:Rust_Y小夜的博客-CSDN博客
欢迎收看,希望对大家有用!
🎯路径
路径有两种形式:
- 绝对路径(absolute path)是以 crate 根(root)开头的全路径;对于外部 crate 的代码,是以 crate 名开头的绝对路径,对于当前 crate 的代码,则以字面值
crate
开头。- 相对路径(relative path)从当前模块开始,以
self
、super
或定义在当前模块中的标识符开头。**绝对路径和相对路径都后跟一个或多个由双冒号(
::
)分割的标识符。**
mod front_of_house { mod hosting { fn add_to_waitlist() {} } } pub fn eat_at_restaurant() { // 绝对路径 crate::front_of_house::hosting::add_to_waitlist(); // 相对路径 front_of_house::hosting::add_to_waitlist(); }
** 错误信息**:
hosting
模块是私有的。换句话说,我们拥有
hosting
模块和
add_to_waitlist
函数的正确路径,但是 Rust 不让我们使用,因为它不能访问私有片段。在 Rust 中,默认所有项(函数、方法、结构体、枚举、模块和常量)对父模块都是私有的。如果希望创建一个私有函数或结构体,你可以将其放入一个模块。
父模块中的项不能使用子模块中的私有项,但是子模块中的项可以使用它们父模块中的项。这是因为子模块封装并隐藏了它们的实现详情,但是子模块可以看到它们定义的上下文。
🎯私有边界
- 模块不经可以组织代码,还可以定义私有边界。
- 如果想把函数或struct等设为私有,可以把他放在某个模块中。
- Rust中所有的条目(函数,方法,struct,enum,模块,常量 )默认私有。
🎯使用pub关键字暴露路径
让我们回头看上面的错误,它告诉我们
hosting
模块是私有的。我们想让父模块中的
eat_at_restaurant
函数可以访问子模块中的
add_to_waitlist
函数,因此我们使用
pub
关键字来标记
hosting
模块。
mod front_of_house { pub mod hosting { fn add_to_waitlist() {} } } pub fn eat_at_restaurant() { // 绝对路径 crate::front_of_house::hosting::add_to_waitlist(); // 相对路径 front_of_house::hosting::add_to_waitlist(); }
**但是**仍有错误,在
mod hosting
前添加了
pub
关键字,使其变成公有的。伴随着这种变化,如果我们可以访问
front_of_house
,那我们也可以访问
hosting
。但是
hosting
的 内容(contents)仍然是私有的;这表明使模块公有并不使其内容也是公有的。模块上的
pub
关键字只允许其父模块引用它,而不允许访问内部代码。因为模块是一个容器,只是将模块变为公有能做的其实并不太多;同时需要更深入地选择将一个或多个项变为公有。
🎯super关键字
我们可以通过在路径的开头使用 **
super
** ,从父模块开始构建相对路径,而不是从当前模块或者 crate 根开始。这类似以
..
语法开始一个文件系统路径。使用
super
允许我们引用父模块中的已知项,这使得重新组织模块树变得更容易 —— 当模块与父模块关联的很紧密,但某天父模块可能要移动到模块树的其它位置。
fn deliver_order() {} mod back_of_house { fn fix_incorrect_order() { cook_order(); super::deliver_order(); } fn cook_order() {} }
🎯创建公共的结构体
我们还可以使用
pub
来设计公有的结构体和枚举,不过关于在结构体和枚举上使用
pub
还有一些额外的细节需要注意。
如果我们在一个结构体定义的前面使用了
pub
,这个结构体会变成公有的,但是这个结构体的字段仍然是私有的。我们可以根据情况决定每个字段是否公有。
mod back_of_house { pub struct Breakfast { pub toast: String, seasonal_fruit: String, } impl Breakfast { pub fn summer(toast: &str) -> Breakfast { Breakfast { toast: String::from(toast), seasonal_fruit: String::from("peaches"), } } } } pub fn eat_at_restaurant() { // 在夏天订购一个黑麦土司作为早餐 let mut meal = back_of_house::Breakfast::summer("Rye"); // 改变主意更换想要面包的类型 meal.toast = String::from("Wheat"); println!("I'd like {} toast please", meal.toast); // 如果取消下一行的注释代码不能编译; // 不允许查看或修改早餐附带的季节水果 // meal.seasonal_fruit = String::from("blueberries"); }
如果我们将枚举设为公有,则它的所有成员都将变为公有。我们只需要在
enum
关键字前面加上
pub
mod back_of_house { pub enum Appetizer { Soup, Salad, } } pub fn eat_at_restaurant() { let order1 = back_of_house::Appetizer::Soup; let order2 = back_of_house::Appetizer::Salad; }
版权归原作者 Y小夜 所有, 如有侵权,请联系我们删除。