- 第1章:基础
Rust 组织管理
本教程到目前为止所有的程序都是在一个文件中编写的,主要是为了方便学习 Rust 语言的语法和概念。
对于一个工程来讲,组织代码是十分重要的。
Rust 中有三个重要的组织概念:箱、包、模块。
"箱"是树状结构的,它的树根是编译器开始运行时编译的源文件所编译的程序。
注意:"二进制程序文件"不一定是"二进制可执行文件",只能确定是是包含目标机器语言的文件,文件格式随编译环境的不同而不同。
一个包最多包含一个库"箱",可以包含任意数量的二进制"箱",但是至少包含一个"箱"(不管是库还是二进制"箱")。
当使用 cargo new 命令创建完包之后,src 目录下会生成一个 main.rs 源文件,Cargo 默认这个文件为二进制箱的根,编译之后的二进制箱将与包名相同。
这些先进的语言的组织单位可以层层包含,就像文件系统的目录结构一样。Rust 中的组织单位是模块(Module)。
mod nation {
mod government {
fn govern() {}
}
mod congress {
fn legislate() {}
}
mod court {
fn judicial() {}
}
}
这是一段描述法治国家的程序:国家(nation)包括政府(government)、议会(congress)和法院(court),分别有行政、立法和司法的功能。我们可以把它转换成树状结构:
nation
├── government
│ └── govern
├── congress
│ └── legislate
└── court
└── judicial
路径分为绝对路径和相对路径。绝对路径从 crate 关键字开始描述。相对路径从 self 或 super 关键字或一个标识符开始描述。例如:
如果你这样做,你一定会发现它不正确的地方:government 模块和其中的函数都是私有(private)的,你不被允许访问它们。
默认情况下,如果不加修饰符,模块中的成员访问权将是私有的。
如果想使用公共权限,需要使用 pub 关键字。
mod nation {
pub mod government {
pub fn govern() {}
} mod congress {
pub fn legislate() {}
} mod court {
fn judicial() {
super::congress::legislate();
}
}
}
fn main() {
nation::government::govern();
}
这段程序是能通过编译的。请注意观察 court 模块中 super 的访问方法。
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);
}
fn main() {
eat_at_restaurant()
}
mod SomeModule {
pub enum Person {
King {
name: String
},
Quene
}
}
fn main() {
let person = SomeModule::Person::King {
name: String::from("Blue")
}; match person {
SomeModule::Person::King {
name
} => {
println!("{}", name);
} _ => {}
}
}
运行结果:
使用过 Java 的开发者在编程时往往非常讨厌最外层的 class 块——它的名字与文件名一模一样,因为它就表示文件容器,尽管它很繁琐但我们不得不写一遍来强调"这个类是文件所包含的类"。
在 Rust 中,模块就像是 Java 中的类包装,但是文件一开头就可以写一个主函数,这该如何解释呢?
每一个 Rust 文件的内容都是一个"难以发现"的模块。
让我们用两个文件来揭示这一点:
main.rs 文件
mod second_module;
fn main() {
println!("This is the main module.");
println!("{}", second_module::message());
}
pub fn message() -> String {
String::from("This is the 2nd module.")
}
This is the main module.
mod nation {
pub mod government {
pub fn govern() {}
}
}
use crate::nation::government::govern;
fn main() {
govern();
}
因为 use 关键字把 govern 标识符导入到了当前的模块下,可以直接使用。
这样就解决了局部模块路径过长的问题。
当然,有些情况下存在两个相同的名称,且同样需要导入,我们可以使用 as 关键字为标识符添加别名:
mod nation {
pub mod government {
pub fn govern() {}
}
pub fn govern() {}
}
use crate::nation::government::govern;
use crate::nation::govern as nation_govern;
fn main() {
nation_govern();
govern();
}
use 关键字可以与 pub 关键字配合使用:
mod nation {
pub mod government {
pub fn govern() {}
}
pub use crate::nation::government::govern;
}
fn main() {
nation::govern();
}
引用标准库
在学习了本章的概念之后,我们可以轻松的导入系统库来方便的开发程序了:
use std::f64::consts::PI;
fn main() {
println!("{}", (PI/ 2.0).sin());
}
网友评论0