# 定义枚举

enum IpAddrKind {
    V4,
    V6,
}

最后一个 逗号 可加,可不加

# 枚举值

let four = IpAddrKind::V4;
let six = IpAddrKind::V6;
fn route(ip_type: IpAddrKind) { }
struct IpAddr {
    kind: IpAddrKind,
    address: String
}

# 枚举成员嵌套任意类型

enum IpAddrKind {
    V4(u8, u8, u8, u8),
    V6(String),
}
let home = IpAddrKind::V4(127, 0, 0, 1);
let loopback = IpAddrKind::V6("::1");

# 标准库如何定义 ip 地址?

struct Ipv4Addr {
    // 省略字段
}
struct Ipv6Addr {
    // 省略字段
}
enum IpAddr {
    V4(Ipv4Addr),
    V6(Ipv6Addr),
}

# 枚举还可以定义 impl

enum Message {
    Quit,
    Move {x: i32, y: i32},
    Write(String),
    ChangeColor(i32, i32, i32),
}
// 与 struct 类似
struct QuitMessage;
struct MoveMessage {x: i32, y: i32};
struct WriteMessage(String);
struct ChangeColorMessage(i32, i32, i32);
// 还可以使用 impl
impl Message {
    fn call(&self) {
        // todo
    }
}
// m.call();

# Option

enum Option<T> {
    Some<T>,
    None,
}

因为常用,所以 Some 和 None 可单独使用。

例如:

let some_number = Some(5);
// None 无法推断类型,因此需要指定类型;
let absent_number: Option<i32> = None;

# match 控制流

fn main() {
    let coin = Coin::Penny;
    let value = match coin {
        Coin::Penny => {
            println!("Penny");
            1
        },
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter => 25,
    };
    println!("{}", value);
}
enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter
}

# 绑定值的形式

fn main() {
    let coin = Coin::Quarter(UsState::Alaska);
    let value = value_in_cents(coin);
    println!("{}", value);
}
fn value_in_cents(coin: Coin) -> u8 {
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter(state) => {
            println!("state: {:?}", state);
            25
        }
    }
}
#[derive(Debug)]
enum UsState {
    Alabama,
    Alaska,
    // -- snip --
}
enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter(UsState)
}

注意事项:

  1. 使用时,不要忘记前缀: Coin::
  2. 使用时,不要忘记符号: =>
  3. 打印时,不要忘记注解和符号: #derive(Debug){:?}

# 匹配 Option<T>

如何获取 Option 里面的值呢?

fn plus_one(x: Option<i32>) -> Option<i32> {
    match x {
        None => None,
        Some(i) => Some(i + 1)
    }
}

# 匹配是穷尽的

match 需要穷尽,如果某个分支没匹配到,就会编译不通过。

# _ 通配符

如果有些不想匹配,则可以用通配符,相当于 default 分支。

let some_u8_value = 0u8;
match some_u8_value {
    1 => println!("one"),
    3 => println!("three"),
    5 => println!("five"),
    7 => println!("seven"),
    _ => (),
}

如果只考虑其中 1 个分支,就啰嗦了,因此有 if let

# if let 简化匹配

let some_u8_value = Some(3);
// if let
if let Some(3) = some_u8_value {
    println!("three");
}

这样就不用每个分支都要穷尽。

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Cecil 微信支付

微信支付

Cecil 支付宝

支付宝

Cecil PayPal

PayPal