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:使用 unwrapexpect

  • 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> 可以使用:
    • matchif let 进行解包。
    • unwrap()(⚠️ 可能 panic)、unwrap_or(default)unwrap_or_else(closure) 提供默认值。
    • map()and_then()filter() 进行变换和过滤。
  • Option<T> 适用于值可能缺失的情况,而 Result<T, E> 适用于可能失败的操作。

Rust 强制你处理 Option<T>,避免了 null 造成的运行时错误,提高代码安全性! 🎯

posted @ 2025-01-31 22:03  代码世界faq  阅读(216)  评论(0)    收藏  举报