Rust 中的枚举类型(enum)是一种用户定义的类型,它可以包含一组特定的值,这些值被称为枚举成员。枚举在编程中非常有用,用于表示有限的、互斥的可能性。Rust 的枚举功能非常强大,不仅可以包含简单的值,还可以包含数据,甚至可以有方法。

1. 定义枚举

使用 enum 关键字定义枚举类型,并列出其可能的值。

rust 复制代码
enum Direction {
    North,
    South,
    East,
    West,
}

在这个例子中,Direction 是一个枚举类型,包含四个成员:NorthSouthEastWest

2. 使用枚举

可以通过枚举的成员来创建该类型的变量。

rust 复制代码
fn main() {
    let dir: Direction = Direction::North;
    println!("Direction: {:?}", dir);
}

输出:

复制代码
Direction: North

3. 枚举匹配(match 表达式)

枚举通常与 match 表达式结合使用,以实现模式匹配。

rust 复制代码
fn main() {
    let dir: Direction = Direction::East;

    match dir {
        Direction::North => println!("Going North"),
        Direction::South => println!("Going South"),
        Direction::East => println!("Going East"),
        Direction::West => println!("Going West"),
    }
}

输出:

复制代码
Going East

4. 带数据的枚举

Rust 的枚举成员可以包含数据,类似于 C++ 的标记联合体。这使得枚举可以表示更复杂的状态。

rust 复制代码
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    Colors(u8, u8, u8),
}

fn main() {
    let msg: Message = Message::Move { x: 10, y: 20 };

    match msg {
        Message::Quit => println!("Quit message"),
        Message::Move { x, y } => println!("Move to ({}, {})", x, y),
        Message::Write(text) => println!("Text message: {}", text),
        Message::Colors(r, g, b) => println!("Colors: {}, {}, {}", r, g, b),
    }
}

输出:

复制代码
Move to (10, 20)

5. 枚举方法

枚举可以有自己的方法,通过 impl 块来定义。

rust 复制代码
enum Status {
    Success,
    Failed(i32),
}

impl Status {
    fn print_status(&self) {
        match self {
            Status::Success => println!("Operation was successful!"),
            Status::Failed(code) => println!("Operation failed with error code: {}", code),
        }
    }
}

fn main() {
    let result: Status = Status::Failed(404);
    result.print_status();
}

输出:

复制代码
Operation failed with error code: 404

6. Option 枚举

Rust 标准库中有一个非常常用的枚举类型:Option,用于表示可能存在或不存在的值。

rust 复制代码
enum Option<T> {
    Some(T),
    None,
}

fn main() {
    let number: Option<i32> = Some(42);
    let absent_number: Option<i32> = None;

    match number {
        Some(n) => println!("The number is: {}", n),
        None => println!("No number"),
    }

    match absent_number {
        Some(n) => println!("The number is: {}", n),
        None => println!("No number"),
    }
}

输出:

复制代码
The number is: 42
No number

7. 结合 if let 的简单匹配

除了 match,还可以使用 if let 表达式对枚举进行简单的模式匹配。

rust 复制代码
fn main() {
    let direction: Direction = Direction::South;

    if let Direction::North = direction {
        println!("Direction is North");
    } else if let Direction::South = direction {
        println!("Direction is South");
    } else {
        println!("Direction is something else");
    }
}

输出:

复制代码
Direction is South

8. 枚举与结构体结合

枚举可以与结构体结合使用,表示复杂的嵌套状态。

rust 复制代码
struct Point {
    x: i32,
    y: i32,
}

enum Shape {
    Circle(f64),
    Rectangle(Point, Point),
    Triangle(Point, Point, Point),
}

fn main() {
    let shape = Shape::Circle(5.0);

    match shape {
        Shape::Circle(radius) => println!("Circle with radius: {}", radius),
        Shape::Rectangle(p1, p2) => println!("Rectangle from {:?} to {:?}", p1, p2),
        Shape::Triangle(p1, p2, p3) => println!("Triangle with points {:?}, {:?}, {:?}", p1, p2, p3),
    }
}

输出:

复制代码
Circle with radius: 5

9.枚举嵌套

在 Rust 中,枚举是可以嵌套的。什么是枚举嵌套枚举嵌套是指在一个枚举类型中嵌套另一个枚举类型。这种嵌套可以是直接嵌套(即在枚举的变体中直接包含另一个枚举类型),也可以是间接嵌套(通过其他数据结构如元组、结构体等包含枚举类型)。

  • 直接嵌套
rust 复制代码
enum OuterEnum {
    VariantA(InnerEnum),
    VariantB,
}

enum InnerEnum {
    InnerA,
    InnerB,
}

fn main() {
    let outer = OuterEnum::VariantA(InnerEnum::InnerA);
    match outer {
        OuterEnum::VariantA(inner) => match inner {
            InnerEnum::InnerA => println!("InnerA"),
            InnerEnum::InnerB => println!("InnerB"),
        },
        OuterEnum::VariantB => println!("VariantB"),
    }
}

OuterEnum 的 VariantA变体直接嵌套了InnerEnum 枚举类型。

  • 间接嵌套
    也可以通过元组或结构体间接嵌套枚举类型。例如:
rust 复制代码
enum OuterEnum {
    VariantA(InnerEnum),
    VariantB(InnerStruct),
}

struct InnerStruct {
    inner: InnerEnum,
}

enum InnerEnum {
    InnerA,
    InnerB,
}

fn main() {
    let outer = OuterEnum::VariantB(InnerStruct { inner: InnerEnum::InnerA });
    match outer {
        OuterEnum::VariantA(inner) => match inner {
            InnerEnum::InnerA => println!("InnerA"),
            InnerEnum::InnerB => println!("InnerB"),
        },
        OuterEnum::VariantB(inner_struct) => match inner_struct.inner {
            InnerEnum::InnerA => println!("InnerA"),
            InnerEnum::InnerB => println!("InnerB"),
        },
    }
}

OuterEnum 的 VariantB 变体通过一个结构体 InnerStruct间接嵌套了 InnerEnum 枚举类型。