Enum的基本使用

Rust使用enum關鍵字定義枚舉類型(Enum)。

例如,定義一個用來描述性別的枚舉類型,名為Gender,它只枚舉兩種值:Male(表示男),Female(表示女)。


#![allow(unused)]
fn main() {
enum Gender {
  Male,   // 男
  Female, // 女
}
}

Enum作為一種數據類型,可以用來限制允許存放的數據。比如某變量的數據類型是Gender類型,那麼該變量只允許存放指定的兩種值:Male或Female,不允許存放其他任何值。也就是說,枚舉類型的每個實例都是從枚舉類型中進行多選一的值。


#![allow(unused)]
fn main() {
let g1: Gender = Gender::Male;
let g2: Gender = Gender::Female;
// let g3: Gender = "male";  // 不允許
}

注意上面變量的類型為Gender,引用Enum內部值的方式為Gender::Male

Gender類型內部的Male和Female稱為枚舉類型的值或者枚舉類型的成員,還可以稱為是枚舉類型的實例。反過來思考,不管是Male成員還是Female成員,它們都屬於Gender類型,是Gender類型的一種值。就像12_u8是u8類型的其中一個值,屬於u8類型。

例如:

enum Gender {
  Male,
  Female,
}

// 參數類型為Gender
fn is_male(g: Gender) -> bool {
  // ...some code...
}

fn main() {
  // 可傳遞Gender已枚舉的值作為參數
  assert!(is_male(Gender::Male));
  assert!(is_male(Gender::Female));
}

再比如,定義一個Choice枚舉類型,用來枚舉由用戶所作出的所有可能選擇。


#![allow(unused)]
fn main() {
enum Choice {
  One,
  Two,
  Three,
  Other,
}
}

Choice枚舉四種可能的值,其中第四種Other表示除前三種選擇之外的所有其他選擇行為,包括錯誤的選擇(比如通過某種手段選擇了不存在的選項)。

Rust中經常會看到類似於Choice的這種用法,在枚舉類型中額外使用一個可以歸納剩餘所有可能的成員,正如上面的Other歸納了所有其他可能的選擇。

其實,前文定義的枚舉類型,其每個成員都有對應的數值。默認第一個成員對應的數值為0,第二個成員的對應的數值為1,後一個成員的數值總是比其前一個數值大1。並且,可以使用=為成員指定數值,但指定值時需注意,不同成員對應的數值不能相同。

例如:


#![allow(unused)]
fn main() {
enum E {
  A,       // 對應數值0
  B,       // 自動加1,對應1
  C = 33,  // 對應33
  D,       // 自動加1,對應34
}
}

定義之後,可使用as將enum成員轉換為對應的數值。

例如,定義英文的星期和數值相對應的枚舉。

enum Week {
  Monday = 1, // 1
  Tuesday,    // 2
  Wednesday,  // 3
  Thursday,   // 4
  Friday,     // 5
  Saturday,   // 6
  Sunday,     // 7
}

fn main(){
  // mon等於1
  let mon = Week::Monday as i32;
}

可在enum定義枚舉類型的前面使用#[repr]來指定枚舉成員的數值範圍,超出範圍後將編譯錯誤。當不指定類型限制時,Rust儘量以可容納數據大小的最小類型。例如,最大成員值為100,則用一個字節的u8類型,最大成員值為500,則用兩個字節的u16。


#![allow(unused)]
fn main() {
// 最大數值不能超過255
#[repr(u8)]  // 限定範圍為`0..=255`
enum E {
  A,
  B = 254,
  C,
  D,        // 256,超過255,編譯報錯
}
}