【Rust】——枚举与模式匹配

时间:2024-03-14 13:34:27

枚举:

允许我们列举所有可能的值来定义一个类型。

如:

定义一个 IpAddrKind 枚举来表现这个概念并列出可能的 IP 地址类型,V4 和 V6。这被称为枚举的 成员variants):

enum IpAddrKind {
    V4,
    V6,
}

枚举值:

    let four = IpAddrKind::V4;
    let six = IpAddrKind::V6;

        注意枚举的成员位于其标识符的命名空间中,并使用两个冒号分开。这么设计的益处是现在 IpAddrKind::V4 和 IpAddrKind::V6 都是 IpAddrKind 类型的。

fn route(ip_kind: IpAddrKind) {}

现在可以使用任一成员来调用这个函数:

    route(IpAddrKind::V4);
    route(IpAddrKind::V6);

将数据附加到枚举的变体中:

    enum IpAddr {
        V4(String),
        V6(String),
    }

    let home = IpAddr::V4(String::from("127.0.0.1"));

    let loopback = IpAddr::V6(String::from("::1"));

优点:

  • 直接将数据附加到枚举的每个成员上,这样就不需要一个额外的结构体
  • 每个成员可以处理不同类型和数量的数据。

如:

    enum IpAddr {
        V4(u8, u8, u8, u8),
        V6(String),
    }

    let home = IpAddr::V4(127, 0, 0, 1);

    let loopback = IpAddr::V6(String::from("::1"));

标准库中的IpAddr

struct Ipv4Addr {
    // --snip--
}

struct Ipv6Addr {
    // --snip--
}

enum IpAddr {
    V4(Ipv4Addr),
    V6(Ipv6Addr),
}

枚举成员中内嵌了多种多样的类型:

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}
  • Quit 没有关联任何数据。
  • Move 类似结构体包含命名字段。
  • Write 包含单独一个 String
  • ChangeColor 包含三个 i32

为枚举定义方法:

例子:

    impl Message {
        fn call(&self) {
            // 在这里定义方法体
        }
    }

    let m = Message::Write(String::from("hello"));
    m.call();