使用super起始的相对路径
fn serve_order() {}
mod back_of_house {
fn fix_incorrect_order() {
cook_order();
super::serve_order(); // 相当于父级目录下调用server_order函数
}
fn cook_order() {}
}
我们可以使用 super 进入back_of_house 父模块,也就是本例中的 crate 根。在这里,我们可以找到 serve_order 。成功!我们认为 back_of_house 模块和 server_order 函数之间可能具有某种关联关系,并且,如果我们要重新组织这个 crate 的模块树,需要一起移动它们。
创建公有的结构体和枚举
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);
// The next line won't compile if we uncomment it; we're not allowed
// to see or modify the seasonal fruit that comes with the meal
// meal.seasonal_fruit = String::from("blueberries"); // 编译不通过
}
因为 back_of_house::Breakfast 结构体的 toast 字段是公有的,所以我们可以在eat_at_restaurant 中使用点号来随意的读写 toast 字段。注意,我们不能在eat_at_restaurant 中使用 seasonal_fruit 字段,因为 seasonal_fruit 是私有的。尝试去除那一行修改 seasonal_fruit 字段值的代码的注释,看看你会得到什么错误!
还请注意一点,因为 back_of_house::Breakfast 具有私有字段,所以这个结构体需要提供一个公共的关联函数来构造示例 Breakfast (这里我们命名为 summer )。如果 Breakfast 没有这样的函数,我们将无法在 eat_at_restaurant 中创建 Breakfast 实例,因为我们不能在eat_at_restaurant 中设置私有字段 seasonal_fruit 的值。
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;
}
因为我们创建了名为 Appetizer 的公有枚举,所以我们可以在 eat_at_restaurant 中使用Soup 和 Salad 成员。如果枚举成员不是公有的,那么枚举会显得用处不大;给枚举的所有成员挨个添加 pub 是很令人恼火的,因此枚举成员默认就是公有的。结构体通常使用时,不必将它们的字段公有化,因此结构体遵循常规,内容全部是私有的,除非使用 pub 关键字。
使用 use 关键字将名称引入作用域
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
use crate::front_of_house::hosting; // 从根出发引入模块
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}
通过在 crate 根增加 use crate::front_of_house::hosting ,现在 hosting 在作用域中就是有效的名称了(绝对引用),我们也可以使用相对引用:
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
use front_of_house::hosting; // 相对引入模块
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}
引用起别名
Rust是不允许同时引入两个相同名字的模块:
use std::fmt;
use std::io;
fn function1() -> fmt::Result {
// --snip-- #
Ok(())
}
fn function2() -> io::Result<()> {
// --snip-- #
Ok(())
}
//如果我们是指定 use std::fmt::Result 和 use std::io::Result ,
//我们将在同一作用域拥有了两个 Result 类型, 当我们使用 Result 时,Rust 则不知道我们要用的是哪个。
use std::fmt::Result;
use std::io::Result as IoResult;
fn function1() -> Result {
// --snip-- #
Ok(())
}
fn function2() -> IoResult<()> {
// --snip-- #
Ok(())
}
使用 pub use 重导出名称
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
pub use crate::front_of_house::hosting; // pub use 使名称可引入任何代码的作用域中 重导出
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}
使用外部包
我们之前使用了rand依赖包,首先在 Cargo.toml 中加入了如下行:
[dependencies]
rand = "0.5.5"
接着,为了将 rand 定义引入项目包的作用域,我们加入一行 use 起始的包名,它以rand 包名开头并列出了需要引入作用域的项。注意标准库( std )对于你的包来说也是外部 crate。因为标准库随 Rust 语言一同分发,无需修改 Cargo.toml 来引入 std ,不过需要通过 use 将标准库中定义的项引入项目包的作用域中来引用它们,比如我们使用的 HashMap :
use std::collections::HashMap;
如果是引入第三方包:
use rand::Rng;
嵌套路径来消除大量的 use 行
当需要引入很多定义于相同包或相同模块的项时,为每一项单独列出一行会占用源码很大的空间。
use std::cmp::Ordering;
use std::io;
// ---snip---
// 修改为
use std::{cmp::Ordering, io};
我们可以在路径的任何层级使用嵌套路径,这在组合两个共享子路径的 use 语句时非常有用:
use std::io;
use std::io::Write;
// 修改为
use std::io::{self, Write}; // 可以在嵌套路径中使用 self
通过 glob 运算符将所有的公有定义引入作用域
use std::collections::*;
将模块分割进不同文件
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
pub use crate::front_of_house::hosting; // pub use 使名称可引入任何代码的作用域中重导出
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}
下面是我们分割后的代码,src下新建了一个front_of_house.rs文件,以及原有的lib.rs文件,首先看看lib.rs代码:
mod front_of_house; // mod关键字声明了模块,Rust 会在与模块同名的文件中查找模块的代码。
pub use crate::front_of_house::hosting; // pub use 使名称可引入任何代码的作用域中 重导出
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}
front_of_house.rs文件代码:
pub mod hosting {
pub fn add_to_waitlist() {}
}