You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fn main() {
fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
None => None,
Some(i) => Some(i + 1),
}
}
let five = Some(5);
let six = plus_one(five);
let none = plus_one(None);
}
匹配必须是可穷尽的、
fn main() {
fn plus_one(x: Option<i32>) -> Option<i32> {
match x { // 编译报错 pattern `None` not covered
Some(i) => Some(i + 1),
}
}
}
私有 vs 公用: 一个模块里的代码默认对其父模块私有。为了使一个模块公用,应当在声明时使用pub mod替代mod。为了使一个公用模块内部的成员公用,应当在声明前使用pub。
use 关键字: 在一个作用域内,use关键字创建了一个成员的快捷方式,用来减少长路径的重复。在任何可以引用crate::garden::vegetables::Asparagus的作用域,你可以通过 use crate::garden::vegetables::Asparagus;创建一个快捷方式,然后你就可以在作用域中只写Asparagus来使用该类型。
mod aa {
pub mod hosting {
pub fn waitlist() {}
}
}
pub fn bb() {
// 绝对路径
crate::aa::hosting::waitlist();
// 相对路径
aa::hosting::waitlist();
}
使用super起始的相对路径
fn deliver_order() {}
mod aa {
fn bb() {
cook_order();
super::deliver_order();
}
fn cook_order() {}
}
bb 函数在 aa 模块中,所以我们使用 super 进入 aa 父模块,在这里可以找到 deliver_order
mod aaa {
pub mod hosting {
pub fn waitlist() {}
}
}
use crate::aaa::hosting;
pub fn eat_at_restaurant() {
hosting::waitlist();
}
use 只能创建 use 所在的特定作用域内的短路径。
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
use crate::front_of_house::hosting;
mod customer {
pub fn eat_at_restaurant() {
// eat_at_restaurant 和 use 不在同一个作用域
hosting::add_to_waitlist(); // error use of undeclared crate or module `hosting`
}
}
枚举
eg:
和struct一起使用
更简洁的方式
真实场景
枚举成员类型可以是多种类型
Option
Option<T>
枚举,不需要显示引入作用域;使用成员也是,不需要Option::
前缀,直接使用Some
、None
。当有一个Some值时,我们知道存在一个值,而这个值保存在Some中。当有个None值时,在某种意义上,它跟空值具有相同的意义:并没有一个有效的值
那么,Option 为什么就比空值要好呢?
因为 Option 和 T(这里 T 可以是任何类型)是不同的类型,编译器不允许像一个肯定有效的值那样使用 Option。例如,这段代码不能编译,因为它尝试将 Option 与 i8 相加:
Rust不知道如何将 Option 与 i8 相加,因为他们类型不同。
i8类型,编译器能确保它总是有一个有效值。
Option类型,需要担心可能没有值。
为了拥有一个可能为空的值,必须显式的将其放入对应类型的
Option<T>
中;当使用这个值时,必须明确的处理为空的情况。只要一个值不是
Option<T>类型,就可以安全的认定它的值不为空
这是Rust经过深思熟虑的设计决策,来限制空值的泛滥以增加Rust代码的安全性
match
表达式就是一个处理枚举的控制流结构:它会根据枚举的成员运行不同的代码。Match控制流结构
match
极为强大的控制流运算符。可以将一个值与一系列的模式相比较模式可以由字面值、变量、通配符和其他内容构成。
相对于
if
使用的条件表达式,必须返回一个布尔值,而这里它可以是任何类型。匹配 Option
匹配必须是可穷尽的、
没有明确处理
None
的情况通配模式和 _ 占位符
if let 简洁控制流
简化:
if let 会失去 match 强制要求的可穷尽检查。
if let 是 match 的一个语法糖
包和 Create
Crate 是 Rust在编译时最小的代码单元。
rustc
编译单个文件(rustc main.rs
),编译器会将那个文件认作一个 crate。crate可以包含模块,模块可以定义在其他文件,然后和crate一起编译。
crate有两种形式: 二进制项和库
二进制项可以编译为可执行程序,它们必须有一个
main
函数来定义当程序被执行的时候所需做的事情。目前我们创建的crate都是二进制项。库并没有
main
函数,它们也不会被编译为可执行程序,它们提供一些函数之类的东西,其他项目也可以使用。比如
rand
crate就提供生成随机数大多数crate指的是库。
crate root 是一个源文件,Rust编译器以它为起点,构建crate的根模块。
包 提供一系列功能的一个或多个crate。
一个 包 会包含一个 Cargo.toml 文件,阐述如何去构建这些crate。
Cargo 就是一个包含构建你代码的二进制项的包。
Cargo 也包含这些二进制项所依赖的库。其他项目也能用 Cargo 库来实现与 Cargo 命令行程序一样的逻辑。
从 crate 根节点开始: 当编译一个 crate, 编译器首先在 crate 根文件(通常,对于一个库 crate 而言是src/lib.rs,对于一个二进制 crate 而言是src/main.rs)中寻找需要被编译的代码。
声明模块: 在 crate 根文件中,你可以声明一个新模块;比如,你用mod garden声明了一个叫做garden的模块。编译器会在下列路径中寻找模块代码:
声明子模块: 在除了 crate 根节点以外的其他文件中,你可以定义子模块。比如,你可能在src/garden.rs中定义了mod vegetables;。编译器会在以父模块命名的目录中寻找子模块代码:
模块中的代码路径: 一旦一个模块是你 crate 的一部分,你可以在隐私规则允许的前提下,从同一个 crate 内的任意地方,通过代码路径引用该模块的代码。举例而言,一个
garden vegetables
模块下的Asparagus
类型可以在crate::garden::vegetables::Asparagus
被找到。私有 vs 公用: 一个模块里的代码默认对其父模块私有。为了使一个模块公用,应当在声明时使用
pub mod
替代mod
。为了使一个公用模块内部的成员公用,应当在声明前使用pub。use 关键字: 在一个作用域内,use关键字创建了一个成员的快捷方式,用来减少长路径的重复。在任何可以引用
crate::garden::vegetables::Asparagus
的作用域,你可以通过use crate::garden::vegetables::Asparagus
;创建一个快捷方式,然后你就可以在作用域中只写Asparagus
来使用该类型。使用super起始的相对路径
bb
函数在aa
模块中,所以我们使用super
进入aa
父模块,在这里可以找到deliver_order
因为
aa:Breakfast
结构体的toast
字段是公共的,所以可以在bb
中使用点号来随意读写toast
字段。注意,不能再bb
中使用seasonal_fruit
字段,因为seasonal_fruit
字段是私有的,所以该字段是不能查看和修改的。因为
aa:Breakfast
具有私有字段,所以这个结构体需要提供一个公共的关联函数来构造Breadkfast
的实例(这里我们命名为summer
)。如果没有这个关联函数,我们将无法在bb
中创建Breakfast
实例,因为不能在bb
中设置私有字段seasonal_fruit
的值。如果枚举(enum)设为公有,则他的所有成员都将变为公有。
如果枚举成员不是公有的,那么枚举会显得用处不大;给枚举的所有成员挨个添加 pub 是很令人恼火的,因此枚举成员默认就是公有的。
结构体通常使用时,不必将它们的字段公有化,因此结构体遵循常规,内容全部是私有的,除非使用 pub 关键字。
use关键字将路径引入作用域
use
只能创建use
所在的特定作用域内的短路径。相同类型——具有相同的Result
使用 as
使用 pub use 重导出名称
不仅将一个名称导入了当前作用域,还允许别人把它导入他们自己的作用域
如果
use
前没加pub
,外部代码想要使用add_to_waitlist
方法,则需要restaurant::front_of_house::hosting::add_to_waitlist()
来调用。现在使用pub use
外部代码可以使用路径restaurant::hosting::add_to_waitlist
即可嵌套路径来消除大量的 use 行
通过 glob 运算符将所有的公有定义引入作用域
如果希望将一个路径下 所有 公有项引入作用域,可以指定路径后跟 *,glob 运算符:
glob 运算符经常用于测试模块 tests 中,这时会将所有内容引入作用域;
模块拆分-多个文件
mod aa;
告诉编译器,去找aa
文件(加载这个文件),继续拆分
文件名:src/aa.rs
文件名:src/aa/hosting.rs
如果将 hosting.rs 放在 src 目录,编译器会认为
hosting
模块中的 hosting.rs 的代码声明于 crate 根,而不是声明为front_of_house
的子模块。mod
关键字声明了模块,Rust 会在与模块同名的文件中查找模块的代码。The text was updated successfully, but these errors were encountered: