(done) 速通 rustlings(19) Option

Option 关键字

在 Rust 里,当某个操作可能会有值也可能没有值时,我们不会用 null,而是使用 Option 枚举:

rust 复制代码
enum Option<T> {
    Some(T),  // 有值,里面包含一个 T 类型的数据
    None,     // 没有值
}
  • 它强制你在使用前处理"无值"的情况,避免空指针错误。
  • 常见的方法包括 unwrap()(直接取值,若是 None 会 panic)、match、if let、map、and_then 等。

具体代码例子如下:

rust 复制代码
// This function returns how much icecream there is left in the fridge.
// If it's before 22:00 (24-hour system), then 5 scoops are left. At 22:00,
// someone eats it all, so no icecream is left (value 0). Return `None` if
// `hour_of_day` is higher than 23.
fn maybe_icecream(hour_of_day: u16) -> Option<u16> {
    // hour_of_day is in 0..=23; if it's >23 we return None
    // before 22:00 we have 5 scoops, at 22 or 23 we have 0 scoops.
    // if hour_of_day > 23 {
    //     None
    // } else if hour_of_day < 22 {
    //     Some(5)
    // } else {
    //     // 22 or 23
    //     Some(0)
    // }

    match hour_of_day {
        0..=21 => Some(5),
        22..=23 => Some(0),
        _ => None,
    }
}

fn main() {
    // You can optionally experiment here.
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn raw_value() {
        // extract the inner value using unwrap since we know it's Some
        let icecreams = maybe_icecream(12).unwrap();

        assert_eq!(icecreams, 5); // Don't change this line.
    }

    #[test]
    fn check_icecream() {
        assert_eq!(maybe_icecream(0), Some(5));
        assert_eq!(maybe_icecream(9), Some(5));
        assert_eq!(maybe_icecream(18), Some(5));
        assert_eq!(maybe_icecream(22), Some(0));
        assert_eq!(maybe_icecream(23), Some(0));
        assert_eq!(maybe_icecream(24), None);
        assert_eq!(maybe_icecream(25), None);
    }
}

if-let 和 while-let

看代码,理解 if-let 和 while-let 的作用

rust 复制代码
fn main() {
    // You can optionally experiment here.
}

#[cfg(test)]
mod tests {
    #[test]
    fn simple_option() {
        let target = "rustlings";
        let optional_target = Some(target);

        // TODO: Make this an if-let statement whose value is `Some`.
        if let Some(word) = optional_target {
            assert_eq!(word, target);
        }
    }

    #[test]
    fn layered_option() {
        let range = 10;
        let mut optional_integers: Vec<Option<i8>> = vec![None];

        for i in 1..=range {
            optional_integers.push(Some(i));
        }

        let mut cursor = range;

        // TODO: Make this a while-let statement. Remember that `Vec::pop()`
        // adds another layer of `Option`. You can do nested pattern matching
        // in if-let and while-let statements.
        // Vec::pop() 会多加一层 Option,所以需要匹配 Some(Some(integer))
        while let Some(Some(integer)) = optional_integers.pop() {
            assert_eq!(integer, cursor);
            cursor -= 1;
        }

        assert_eq!(cursor, 0);
    }
}

match关键字 与 Option关键字 配合

match 中不需要使用 let 去声明 p,模式匹配中隐含了 let 声明关键字

rust 复制代码
#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let optional_point = Some(Point { x: 100, y: 200 });

    // Solution 1: Matching over the `Option` (not `&Option`) but without moving
    // out of the `Some` variant.
    match optional_point {
        Some(ref p) => println!("Co-ordinates are {},{}", p.x, p.y),
        //   ^^^ added
        _ => panic!("No match!"),
    }

    // Solution 2: Matching over a reference (`&Option`) by added `&` before
    // `optional_point`.
    match &optional_point {
        Some(p) => println!("Co-ordinates are {},{}", p.x, p.y),
        _ => panic!("No match!"),
    }

    println!("{optional_point:?}");
}

相关推荐
@atweiwei1 小时前
rust所有权机制详解
开发语言·数据结构·后端·rust·内存·所有权
shimly1234562 小时前
(done) 速通 rustlings(24) 错误处理2 --- 涉及Traits
rust
shimly1234562 小时前
(done) 速通 rustlings(23) 特性 Traits
rust
shimly1234563 小时前
(done) 速通 rustlings(17) 哈希表
rust
shimly1234564 小时前
(done) 速通 rustlings(15) 字符串
rust
shimly1234565 小时前
(done) 速通 rustlings(22) 泛型
rust
yezipi耶不耶5 小时前
我在 RTMate 里使用的高并发连接管理利器: DashMap
websocket·rust
初恋叫萱萱11 小时前
深入解析 Rust + LLM 开发:手把手教你写一个 AI 运维助手
运维·人工智能·rust
shimly12345619 小时前
(done) 速通 rustlings(9) 分支跳转
rust