Day 3:列舉(Enums)

學習目標

  • 定義列舉與帶資料的變體(variant)
  • 理解列舉能攜帶不同型別的資料
  • 會搭配 match 使用

今日重點

基本列舉

enum IpAddrKind {
    V4,
    V6,
}

攜帶資料的變體

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

let home = IpAddr::V4(127, 0, 0, 1);
let loopback = IpAddr::V6(String::from("::1"));

每個變體可以帶**不同型別**的資料,這是列舉在 Rust 的強大之處。

列舉方法(impl)

impl IpAddr {
    fn display(&self) {
        match self {
            IpAddr::V4(a, b, c, d) => println!("{}.{}.{}.{}", a, b, c, d),
            IpAddr::V6(addr) => println!("{}", addr),
        }
    }
}

通用列舉範例

enum Message {
    Quit,                              // 無資料
    Move { x: i32, y: i32 },           // 有名稱的欄位
    Write(String),                     // 單一 String
    ChangeColor(i32, i32, i32),        // 三個值
}

練習

enum Shape {
    Circle(f64),           // 半徑
    Rectangle(f64, f64),   // 寬、高
    Square(f64),           // 邊長
}

impl Shape {
    fn area(&self) -> f64 {
        match self {
            Shape::Circle(r) => std::f64::consts::PI * r * r,
            Shape::Rectangle(w, h) => w * h,
            Shape::Square(s) => s * s,
        }
    }
}
1. 實作 Shape::area 並計算各種形狀面積。 2. 想想為什麼用 enum 比用多個 struct 更能統一處理。

自我檢查

  • 能定義帶資料的列舉
  • 能對列舉寫 impl 方法並用 match
  • 理解列舉可攜帶不同型別資料

深入連結

  • The Book 第 6 章「Defining an Enum」