大家好,
今天是学习 Rust 的第十天。昨天我们讨论了如何使用 structs
将相关数据分组在一起。今天我们来看一个类似的概念,即 enums
。
Rust 中的枚举是一种数据类型,允许你通过列举可能的值来定义类型,提供了一种简洁而类型安全的方式来表示不同的选择。
enum Day {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday,
}
fn main() {
let today = Day::Monday;
}
这就是 enums
的基本概念……
如果我们要用编程语言来存储每一天要学习 Rust 的情况。我们会像这样使用 structs
enum Day {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday,
}
struct TimeTable {
day: Day,
language: String,
}
fn main() {
let day1 = TimeTable {
day: Day::Monday,
language: String::from("Rust"),
};
}
另一种方式是将值存储在 enums
中。
enum Day {
Monday(String),
Tuesday(String),
Wednesday(String),
Thursday(String),
Friday(String),
Saturday(String),
Sunday(String),
}
struct TimeTable {
day: Day,
language: String,
}
fn main() {
let day1 = Day::Monday(String::from("Rust"));
}
就像我们为 structs
做的那样,我们可以创建一个 impl
块来在 enums
中实现方法。
// 定义一个枚举叫做 Shape 代表不同的几何形状
enum Shape {
Circle(f64), // 变体 Circle 接受一个半径
Square(f64), // 变体 Square 接受一个边长
}
// 在 Shape 枚举上实现方法
impl Shape {
// 计算形状的面积的方法
fn area(&self) -> f64 {
match *self {
Shape::Circle(radius) => 3.14 * radius * radius,
Shape::Square(side_length) => side_length * side_length,
}
}
}
fn main() {
// 创建不同形状的实例
let circle = Shape::Circle(2.0);
let square = Shape::Square(3.0);
// 计算并打印不同形状的面积
println!("圆的面积: {:.2}", circle.area());
println!("正方形的面积: {:.2}", square.area());
}
圆的面积: 12.57
正方形的面积: 9.00
Rust 中的 Option enum
表示值的存在或不存在,提供了一种简洁而类型安全的方式来处理可能存在或缺失值的情况。
如果我们有一个可能为空值的值,Rust 并没有 null 类型,我们可以使用 Option 枚举来处理这些情况。
这样做可以强制类型系统要求我们处理空值情况,从而使代码更安全。
Some
用于值存在时None
用于值不存在时match
操作来列举这两种情况。fn get_first_element(numbers: &[i32]) -> Option<i32> {
if let Some(&first) = numbers.first() {
Some(first) // 如果存在,返回 Some 包裹的第一个元素
} else {
None // 如果切片为空,则返回 None
}
}
get_first_element
函数以整数切片 numbers
作为参数。.first()
方法来获取一个包含切片第一个元素的 Option。.first()
返回 Some(&first)
,其中 first
是对第一个元素的引用。该函数对 Option 进行模式匹配:
Some
,它提取 first
的值并将其包装在另一个 Some
中,有效地解包引用。None
,表示切片为空,则返回 None
。fn main() {
let x: i8 = 10;
let y: Option<i8> = Some(14);
let sum = x + y;
}
这段代码会导
致错误,因为我们不能将 i8
加到 Option
,因为它们是不同的数据类型。
为了完成这个操作,我们可以使用 unwrap_or()
方法。
unwrap_or(data)
如果存在,则返回 Option enum
的值,如果不存在,则返回 data
。
fn main() {
let x: i8 = 10;
let y: Option<i8> = Some(14);
let sum = x + y.unwrap_or(0);
println!("{}", sum);
}
24
我们在猜数字游戏中使用了 match
,它用于检查多种情况并针对每个值运行特定的代码块。
这是一个简单的例子:
fn main() {
let number = 5;
match number {
1 => println!("It's one!"),
2 => println!("It's two!"),
3 | 4 => println!("It's three or four!"),
8 => {
println!("This is a multi-line function in a match expression");
},
_ => println!("It's something else!"),
}
}
match
关键字对 number
的值进行模式匹配。match
表达式中的每个模式后面都跟着 =>
,指示匹配模式时要执行的代码。number
匹配模式 1
,则打印消息 “It’s one!”。number
匹配模式 2
,则打印消息 “It’s two!”。number
匹配模式 3
或 4
,则打印消息 “It’s three or four!”。number
匹配模式 8
,则执行大括号内的代码,打印 “This is a multi-line function in a match expression”。_
模式充当通配符,匹配任何未明确列出的值。如果 number
不匹配任何指定的模式,则使用通配符模式 _
,并打印消息 “It’s something else!”。在这个具体例子中,由于 number
是 5
,它不匹配任何特定模式,因此使用通配符模式 _
,并打印消息 “It’s something else!”。
在学习 Rust 的第十天,我们深入探讨了枚举和模式匹配。以下是我们讨论的内容摘要:
impl
块在枚举上实现方法。我们通过创建计算不同几何形状面积的方法来演示了这一点,这些形状由枚举表示。Option
枚举,它通常用于处理值可能存在或不存在的情况。我们探讨了 Some
表示值存在,而 None
表示值不存在。此外,我们学习了如何使用 unwrap_or
方法来处理我们需要从 Option
中提取值或者在值不存在时提供默认值的情况。match
关键字进行模式匹配,它允许我们检查多种情况并根据匹配的模式执行特定的代码。我们演示了如何使用 match
来处理各种情况并执行相应的代码块。