Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

Rust辞典

  1. トップページ
  2. Rust辞典
  3. enum / バリアント定義

enum / バリアント定義

Rustのenum(列挙型)は複数のバリアントを持つ型です。各バリアントはデータを持つことができ、タプル形式・構造体形式・データなしの3種類があります。

構文
// データなしのバリアントです。
enum Direction {
    North,
    South,
    East,
    West,
}

// タプルバリアント(データを持ちます)。
enum Shape {
    Circle(f64),          // 半径
    Rectangle(f64, f64),  // 幅, 高さ
}

// 構造体バリアント(フィールドに名前があります)。
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(u8, u8, u8),
}

// 使用例です。
let dir = Direction::North;
let s = Shape::Circle(3.0);
let msg = Message::Move { x: 10, y: 20 };
バリアントの種類
種類構文概要
ユニットバリアントFoo,データを持たないバリアントです。
タプルバリアントFoo(T1, T2),タプル形式でデータを持つバリアントです。
構造体バリアントFoo { x: T1, y: T2 },フィールド名付きでデータを持つバリアントです。
Option<T>Some(T) / None値があるかないかを表す標準ライブラリのenum です。
Result<T, E>Ok(T) / Err(E)成功・失敗を表す標準ライブラリのenum です。
サンプルコード
#[derive(Debug)]
enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter,
}

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

#[derive(Debug)]
enum Event {
    KeyPress(char),
    MouseMove { x: i32, y: i32 },
    Click { button: u8, x: i32, y: i32 },
    Resize(u32, u32),
    Quit,
}

impl Coin {
    // バリアントに対応する値を返すメソッドです。
    fn value_in_cents(&self) -> u32 {
        match self {
            Coin::Penny => 1,
            Coin::Nickel => 5,
            Coin::Dime => 10,
            Coin::Quarter => 25,
        }
    }
}

fn process_event(event: &Event) {
    match event {
        Event::KeyPress(c) => println!("キー入力: {}", c),
        Event::MouseMove { x, y } => println!("マウス移動: ({}, {})", x, y),
        Event::Click { button, x, y } => {
            println!("クリック: ボタン{} at ({}, {})", button, x, y)
        }
        Event::Resize(w, h) => println!("リサイズ: {}x{}", w, h),
        Event::Quit => println!("終了"),
    }
}

fn main() {
    // ユニットバリアントです。
    let coin = Coin::Quarter;
    println!("{:?} = {} セント", coin, coin.value_in_cents());

    // タプルバリアントです。
    let home = IpAddr::V4(192, 168, 1, 1);
    let loopback = IpAddr::V6(String::from("::1"));
    println!("{:?}", home);
    println!("{:?}", loopback);

    // 各種バリアントを使います。
    let events = vec![
        Event::KeyPress('a'),
        Event::MouseMove { x: 100, y: 200 },
        Event::Click { button: 1, x: 50, y: 75 },
        Event::Resize(1920, 1080),
        Event::Quit,
    ];

    for event in &events {
        process_event(event);
    }
}
概要

Rustのenumは他の言語の列挙型より強力で、各バリアントが異なる型・数のデータを持てます。これはC言語の判別共用体(tagged union)に相当します。

enumのバリアントは型名と同じ名前空間に属するため、『use Direction::*;』とすることで『North』のように短く書けます。

enumへのメソッド追加とmatchによる処理は『impl enum / match でのパターン分岐』を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。