简单枚举

enum Ordering {
    Less,
	Equal,
	Greater 
}

在内存中,C 式枚举的值存储为整数。有时候可能要告诉 Rust 使用 什么整数:

enum HttpStatus {
    Ok = 200,
    NotModified = 304,
    NotFound = 404,
    ...
}

Rust 默认使用能够容纳它们的最小内置整数类型来存储 C 式枚举。 多数情况下一个字节就够了。

use std::mem::size_of;
assert_eq!(size_of::<Ordering>(), 1); 
assert_eq!(size_of::<HttpStatus>(), 2); // 一个u8装不下404

枚举也可以有方法,同样跟结构体一样:

impl TimeUnit {  
/// 返回这个时间单位的复数名词  
fn plural(self) -> &'static str {
        match self {
            TimeUnit::Seconds => "seconds",
            TimeUnit::Minutes => "minutes",
            TimeUnit::Hours => "hours",
            TimeUnit::Days => "days",
            TimeUnit::Months => "months",
            TimeUnit::Years => "years"
 
} }
/// 返回这个时间单位的单数名词  
fn singular(self) -> &'static str {
        self.plural().trim_right_matches('s')
    }
}

包含数据的枚举

元组变体枚举

#[derive(Copy, Clone, Debug, PartialEq)]
enum RoughTime {
    InThePast(TimeUnit, u32),
    JustNow,
    InTheFuture(TimeUnit, u32)
 
}

枚举值也可以是结构体变体

enum Shape {
    Sphere { center: Point3d, radius: f32 },
    Cuboid { corner1: Point3d, corner2: Point3d }
}

泛型枚举

enum Result<T, E> {
Ok(T),
Err(E) 
}

模式

let calendar =
    match settings.get_string("calendar") {
 
        "gregorian" => Calendar::Gregorian,
        "chinese" => Calendar::Chinese,
        "ethiopian" => Calendar::Ethiopian,
        other => return parse_error("calendar", other)
 
};

other 作为一个兜底模式,与上个例子中的 n 类似。 它们都相当于 switch 语句中的 default 分支,用于匹配不与任何其 他模式匹配的值

对于引用,Rust 支持两种模式:ref 模式和 & 模式;前者借用匹配 值的元素,后者匹配引用 匹配不可复制的值会转移值

match account {
    Account { name, language, .. } => {
        ui.greet(&name, &language);
		ui.show_settings(&account); // 错误:使用转移的值account }
}

需要一种模式来 而不转移匹配的值。关键字 ref 就是做这个用的:

match account {
    Account { ref name, ref language, .. } => {
        ui.greet(name, language);
		ui.show_settings(&account); // 没问题 }
}

还可以使用 ref mut 借用 mut 引用

以 & 开头的模式匹配引用

match sphere.center() {
    &Point3d { x, y, z } => ...
}

表达式和模式天生是相反 的。表达式 (x, y) 用两个值创建一个新元组,模式 (x, y) 则相 反:它匹配元组并将其破坏后取出两个值。对 & 而言也一样:表达式 中的 & 创建引用,模式中的 & 匹配引用

在表达式中,|是 操作符,但在这里它更像正则表达式中的 | 符号 使用 … 可以匹配某个范围中的值。范围模式包含起点值和终点值, 即 ‘0’ … ‘9’ 匹配所有 ASCII 数字:

match next_char {
    '0' ... '9' =>
 
        self.read_number(),
    'a' ... 'z' | 'A' ... 'Z' =>
 
        self.read_word(),
    ' ' | '\t' | '\n' =>
        self.skip_whitespace(),
    _ =>
 
}
 
self.handle_punctuation()

模式中的范围是 (inclusive)的,因此 ‘0’ 和 ‘9’ 都匹配 ‘0’ … ‘9’。相应地,范围表达式(中间是两个点,比如 for n in 0..100)则是半开放或 的(包含 0 但不包含 100)。之所以存在 这种不一致的现象,主要是因为互斥范围对循环和片段更有用,而全 纳范围在模式匹配中更有用

  • 复习 Rust 枚举和模式 (@2024-01-22)