掌握Rust枚举定义、Option类型、模式匹配枚举,以及代数数据类型概念。
enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
enum Shape {
Circle { radius: f64 },
Rectangle { width: f64, height: f64 },
Triangle { a: f64, b: f64, c: f64 },
}
fn area(s: &Shape) -> f64 {
match s {
Shape::Circle { radius } => std::f64::consts::PI * radius * radius,
Shape::Rectangle { width, height } => width * height,
Shape::Triangle { a, b, c } => {
let s = (a + b + c) / 2.0;
(s * (s-a) * (s-b) * (s-c)).sqrt()
}
}
}
fn main() {
let home = IpAddr::V4(127, 0, 0, 1);
let loopback = IpAddr::V6(String::from("::1"));
let shapes: Vec<Shape> = vec![
Shape::Circle { radius: 5.0 },
Shape::Rectangle { width: 3.0, height: 4.0 },
Shape::Triangle { a: 3.0, b: 4.0, c: 5.0 },
];
for s in &shapes {
println!("面积: {:.2}", area(s));
}
}
✅ 编译验证通过
Option<T>替代:
enum Option<T> {
Some(T),
None,
}
编译器强制你处理None的情况,不会遗漏空值检查。
fn divide(a: f64, b: f64) -> Option<f64> {
if b == 0.0 { None } else { Some(a / b) }
}
fn main() {
let result = divide(10.0, 3.0);
match result {
Some(v) => println!("结果: {:.2}", v),
None => println!("除零错误"),
}
// if let简洁写法
if let Some(v) = divide(10.0, 2.0) {
println!("if let: {}", v);
}
// unwrap — None时panic
// let v = divide(10.0, 0.0).unwrap(); // 💥
// unwrap_or — 提供默认值
let v = divide(10.0, 0.0).unwrap_or(0.0);
println!("默认值: {}", v);
}
✅ 编译验证通过
fn main() {
let some: Option<i32> = Some(42);
let none: Option<i32> = None;
// map — 转换Some中的值
let doubled = some.map(|x| x * 2); // Some(84)
let none_d = none.map(|x| x * 2); // None
// and_then — 链式操作(flatMap)
let result = Some(2)
.and_then(|x| divide(10.0, x as f64))
.map(|v| v * 3.0);
// filter — 条件过滤
let positive = Some(5).filter(|&x| x > 0); // Some(5)
let negative = Some(-5).filter(|&x| x > 0); // None
// unwrap_or_else
let v = None.<i32>.unwrap_or_else(|| 0);
// ok_or — 转为Result
let r = None.<i32>.ok_or("not found");
}
fn divide(a: f64, b: f64) -> Option<f64> {
if b == 0.0 { None } else { Some(a / b) }
}
✅ 编译验证通过
Rust枚举是代数数据类型(ADT),有两种:
类型状态数量:enum是变体之和,struct是字段之积。
enum List {
Cons(i32, Box<List>),
Nil,
}
fn sum(list: &List) -> i32 {
match list {
List::Cons(head, tail) => head + sum(tail),
List::Nil => 0,
}
}
fn main() {
let list = List::Cons(1,
Box::new(List::Cons(2,
Box::new(List::Cons(3,
Box::new(List::Nil))))));
println!("sum = {}", sum(&list));
}
✅ 编译验证通过
用Option的链式方法实现:解析字符串为整数→除以2→转换为字符串。
用枚举实现二叉搜索树,支持insert和search。
用枚举实现一个TCP连接状态机(Closed→Listen→SynSent→Established)。
掌握枚举和Option——Rust类型系统的核心工具
以下资源帮助你深入学习本课主题:
本课涉及的核心概念,确保你理解每一个:
| 术语 | 说明 |
|---|---|
| 所有权 | Rust内存管理的核心机制,每个值有唯一所有者 |
| 借用 | 通过引用访问数据,不获取所有权 |
| 生命周期 | 引用有效的范围,编译期分析工具 |
| trait | Rust的接口/抽象机制,类似其他语言的接口 |
| 泛型 | 参数化类型,零成本抽象 |
| 模式匹配 | 强大的数据解构和分支机制 |
| 零成本抽象 | 高层抽象不引入运行时开销 |
| fearless concurrency | 编译器保证线程安全 |
Q: Rust学习曲线真的很陡吗?
A: 前期确实需要适应所有权和借用检查器,但一旦理解了,这些概念会让你的代码更可靠。大多数人2-4周就能上手。
Q: Rust适合什么项目?
A: 系统编程、Web服务、CLI工具、嵌入式、WASM、网络服务、数据库等。基本上需要性能和安全的地方都适合。
Q: 遇到编译错误怎么办?
A: Rust编译器的错误信息非常友好!仔细阅读,通常会指出问题所在和修复建议。也可以用cargo clippy获取更多提示。