10 rust基础- Option类型
Rust 中的 Option<T> 类型学习
Option<T> 是 Rust 标准库中的一个枚举类型,表示一个值要么是 某个类型的值 (Some(T)),要么是 空 (None)。它用于处理可能不存在的值,而不是使用 null(Rust 没有 null)。
Option<T> 是 Rust 处理 可选值(nullable) 的标准方式,能够 强制程序员显式地处理值缺失的情况,避免 null 造成的空指针异常(NullPointerException)。
1. Option<T> 的定义
Option<T> 的定义如下:
enum Option<T> {
Some(T),
None,
}
Some(T):表示有值,内部存储类型为T。None:表示没有值,相当于null。
例子:使用 Option<T> 表示可能缺失的值
fn divide(a: f64, b: f64) -> Option<f64> {
if b == 0.0 {
None
} else {
Some(a / b)
}
}
fn main() {
let result1 = divide(10.0, 2.0);
let result2 = divide(10.0, 0.0);
println!("{:?}", result1); // Some(5.0)
println!("{:?}", result2); // None
}
解析:
- 当
b != 0.0,返回Some(结果),表示计算成功。 - 当
b == 0.0,返回None,表示除法失败。
2. 处理 Option<T> 的几种方式
Rust 强制 你在使用 Option<T> 之前,先显式地处理 None,有几种方式:
方法 1:使用 match 语句
fn print_division(a: f64, b: f64) {
match divide(a, b) {
Some(result) => println!("结果: {}", result),
None => println!("无法除以零"),
}
}
fn main() {
print_division(10.0, 2.0); // 输出: 结果: 5.0
print_division(10.0, 0.0); // 输出: 无法除以零
}
方法 2:使用 if let
fn main() {
let result = divide(10.0, 2.0);
if let Some(value) = result {
println!("计算结果: {}", value);
} else {
println!("计算失败");
}
}
方法 3:使用 unwrap 或 expect
unwrap()直接取出Some(T)的值,如果是None,程序 panic(崩溃):
fn main() {
let value = Some(10);
println!("{}", value.unwrap()); // 输出: 10
let none_value: Option<i32> = None;
println!("{}", none_value.unwrap()); // panic! 程序崩溃
}
expect("错误信息")在None时会给出更详细的错误信息:
fn main() {
let value = None;
println!("{}", value.expect("值不能为空!")); // panic! 并打印: "值不能为空!"
}
⚠️unwrap() 和 expect() 可能导致程序崩溃,应谨慎使用!
3. Option<T> 相关方法
(1)is_some() 和 is_none()
检查 Option 是否有值:
fn main() {
let some_value = Some(42);
let none_value: Option<i32> = None;
println!("{}", some_value.is_some()); // true
println!("{}", some_value.is_none()); // false
println!("{}", none_value.is_some()); // false
println!("{}", none_value.is_none()); // true
}
(2)unwrap_or(default)
提供默认值:
fn main() {
let some_value = Some(42);
let none_value: Option<i32> = None;
println!("{}", some_value.unwrap_or(100)); // 42
println!("{}", none_value.unwrap_or(100)); // 100
}
(3)unwrap_or_else(closure)
使用闭包计算默认值:
fn main() {
let none_value: Option<i32> = None;
let result = none_value.unwrap_or_else(|| {
println!("计算默认值...");
99
});
println!("{}", result); // 先打印"计算默认值...",然后输出 99
}
(4)map()
对 Some 里面的值进行操作:
fn main() {
let number = Some(10);
let double = number.map(|x| x * 2); // 如果是 Some,则执行 *2
println!("{:?}", double); // Some(20)
let none_value: Option<i32> = None;
let result = none_value.map(|x| x * 2);
println!("{:?}", result); // None
}
(5)and_then()
类似 map(),但适用于返回 Option<T> 的情况:
fn square(x: i32) -> Option<i32> {
Some(x * x)
}
fn main() {
let number = Some(4);
let result = number.and_then(square);
println!("{:?}", result); // Some(16)
let none_value: Option<i32> = None;
let result = none_value.and_then(square);
println!("{:?}", result); // None
}
(6)filter()
如果值符合条件,则保留 Some(T),否则变为 None:
fn main() {
let number = Some(10);
let even_number = number.filter(|x| x % 2 == 0);
println!("{:?}", even_number); // Some(10)
let odd_number = Some(11);
let result = odd_number.filter(|x| x % 2 == 0);
println!("{:?}", result); // None
}
4. Option<T> 与 Result<T, E> 的对比
| 特性 | Option<T> |
Result<T, E> |
|---|---|---|
| 作用 | 表示 "有值/无值" | 表示 "成功/失败" |
| 成功状态 | Some(T) |
Ok(T) |
| 失败状态 | None |
Err(E) |
| 适用场景 | 值可能不存在,如 find() |
可能出错的操作,如 parse() |
例子:
fn get_number(value: &str) -> Result<i32, String> {
value.parse::<i32>().map_err(|_| "解析失败".to_string())
}
相比 Option<T>,Result<T, E> 还能提供错误信息。
总结
Option<T>让 Rust 显式 处理可能缺失的值,避免null引发的问题。Some(T)表示有值,None表示无值。- 处理
Option<T>可以使用:match、if let进行解包。unwrap()(⚠️ 可能 panic)、unwrap_or(default)、unwrap_or_else(closure)提供默认值。map()、and_then()、filter()进行变换和过滤。
Option<T>适用于值可能缺失的情况,而Result<T, E>适用于可能失败的操作。
Rust 强制你处理 Option<T>,避免了 null 造成的运行时错误,提高代码安全性! 🎯

浙公网安备 33010602011771号