枚举(enum)

Rust的枚举非常强大,代表一系列子数据类型的集合。类似于Java风格的枚举。

最简单的枚举

// enums
enum Direction {    // 四个方向
    West,
    North,
    Sourth,
    East,
}

元组结构体型的枚举

枚举元素是一种元组结构体。这样枚举元素就可以拥有字段了。

#[derive(Debug)]
enum IpAddr {
    V4(String),
    V6(String)
}

fn main() {
    let ipv4 = IpAddr::V4(String::from("127.0.0.1"));
    println!("{:?}",ipv4);    // 打印:V4("127.0.0.1")
}

标准库std::net::IpAddr有如下类似的定义:

#[derive(Debug)]
struct IpAddrV4 {
    // ...
}

#[derive(Debug)]
struct IpAddrV6 {
    // ...
}

#[derive(Debug)]
enum IpAddr {
    V4(IpAddrV4),
    V6(IpAddrV6)
}

fn main() {
    let ipv4 = IpAddr::V4(IpAddrV4{});
    println!("{:?}",ipv4);  // 打印:V4(IpAddrV4)
}

结构体型的枚举

枚举元素是一种结构体。

#[derive(Debug)]
enum IpAddr {
    V4{x1:u8,x2:u8,x3:u8,x4:u8},
    V6{x1:u16,x2:u16,x3:u16,x4:u16,x5:u16,x6:u16,x7:u16,x:8:u16}
}

fn main() {
    let ipv4 = IpAddr::V4{x1:127,x2:0,x3:0,x4:1};
    println!("{:?}",ipv4);
}

枚举元素可以是不同的复合数据类型。

例:如下,V4、V6的字段数不同,是两种不同类型。

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

fn main() {
    let ipv4 = IpAddr::V4(127,0,0,1);
    println!("{:?}",ipv4);    // 打印:V4(127, 0, 0, 1)
}

由此可见Rust的enum子类型可以拥有不同的类型。这也是Rust比Java enum强大的地方。

Rust enum的每一个元素都可以支持不同类型的参数。

例:如下枚举,每个子类型都拥有不同结构的复合类型。

// enums
enum Message {
    Quit,
    ChangeColor(i32, i32, i32),
    Move { x: i32, y: i32 },
    Write(String),
}

说明:Message的4个元素是4中不同类型。

访问枚举元素

使用::来访问枚举元素。

let direction: Direction = Direction::West
// 或
let message: Message = Message::Move { x: 3, y: 4 };

访问枚举类型内部的值需要使用模式匹配。

enum SpecialPoint {
    Point(i32, i32),
    Special(String),
}

fn main() {
    let sp = SpecialPoint::Point(0, 0);
    match sp {
        SpecialPoint::Point(x, y) => {
            println!("I'am SpecialPoint(x={}, y={})", x, y);
        }
        SpecialPoint::Special(why) => {
            println!("I'am Special because I am {}", why);
        }
    }
}

更多关于枚举的模式匹配,请参看本书模式匹配一节中的内容。

results matching ""

    No results matching ""