Menu
Coddy logo textTech

データバリアントのマッチング

CoddyのRustジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 16/61。

前のレッスンでは、異なるバリアントを処理するために enum のメソッド内で match を使用しました。ここでは、match がそれらのバリアント内に格納されたデータを実際にどのように取り出すのかに焦点を当てます。これは destructuring と呼ばれるテクニックです。

データを holds する enum バリアントに match すると、そのデータをパターン内で直接変数にバインドできます。

enum Event {
    Click { x: i32, y: i32 },
    KeyPress(char),
    Resize(u32, u32),
}

fn handle_event(event: Event) {
    match event {
        Event::Click { x, y } => {
            println!("Clicked at ({}, {})", x, y);
        }
        Event::KeyPress(key) => {
            println!("Key pressed: {}", key);
        }
        Event::Resize(width, height) => {
            println!("Resized to {}x{}", width, height);
        }
    }
}

各アームは、バリアントの構造に基づいて異なる方法でデータを抽出します。構造体のようなバリアントでは、{ field_name }を使って名前付きフィールドを取り出します。タプルバリアントでは、(width, height)のような位置変数を使います。

選択した変数名は、その match アーム内で使用できるようになります。これは、どのバリアントを持っているかを同時に確認し、さらにそのペイロードにアクセスできるため強力です。

コンパイラによってすべてのバリアントを handle でき、抽出された値はすぐに使用できます。追加の手順は必要ありません。

challenge icon

チャレンジ

簡単

さまざまな種類のユーザーコマンドを処理するコマンドプロセッサを構築しましょう。各コマンドは異なるデータを持ち、プロセッサはパターンマッチングを使用してそのデータを抽出し、適切な応答を生成します。

コードを整理するために、2つのファイルを作成します。

  • command.rs:3つのバリアントを持つ public Command enum を定義します。
    • Say:単一の String メッセージを保持します(タプル構文)
    • Move:named フィールドを保持します:direction(String)と steps(u32)
    • Calculate:加算する数値を表す2つの i32 値を保持します(タプル構文)
    次に、match を使用して各バリアントを destructure し、実行したアクションを説明する String を return する execute method を implement します。
  • main.rs:command モジュールを取り込み、提供された inputs を使って各 command バリアントのインスタンスを1つずつ作成し、それぞれに対して execute method を呼び出して results を出力します。

execute method は各バリアントを destructure してそのデータにアクセスし、次の exact な形式でメッセージを return する必要があります。

  • Say の場合:Saying: {message}
  • Move の場合:Moving {steps} steps {direction}
  • Calculate の場合:{a} + {b} = {sum}

出力には、各 command の result がそれぞれ独自の行に表示される必要があります。

Saying: {message}
Moving {steps} steps {direction}
{a} + {b} = {sum}

たとえば、say message が "Hello world"5 steps の Move が "north"、Calculate が 1025 の場合、出力は次のようになります。

Saying: Hello world
Moving 5 steps north
10 + 25 = 35

5つの inputs を受け取ります:say message、direction、steps の数、そして Calculate する2つの数です。

自分で試してみよう

mod command;

use command::Command;

fn main() {
    // 入力を読み取る
    let mut say_message = String::new();
    std::io::stdin().read_line(&mut say_message).expect("Failed to read line");
    let say_message = say_message.trim().to_string();

    let mut direction = String::new();
    std::io::stdin().read_line(&mut direction).expect("Failed to read line");
    let direction = direction.trim().to_string();

    let mut steps_input = String::new();
    std::io::stdin().read_line(&mut steps_input).expect("Failed to read line");
    let steps: u32 = steps_input.trim().parse().expect("Failed to parse steps");

    let mut num1_input = String::new();
    std::io::stdin().read_line(&mut num1_input).expect("Failed to read line");
    let num1: i32 = num1_input.trim().parse().expect("Failed to parse num1");

    let mut num2_input = String::new();
    std::io::stdin().read_line(&mut num2_input).expect("Failed to read line");
    let num2: i32 = num2_input.trim().parse().expect("Failed to parse num2");

    // TODO: say_message を使用して Say コマンドを作成し、実行する
    
    // TODO: direction と steps を使用して Move コマンドを作成し、実行する
    
    // TODO: num1 と num2 を使用して Calculate コマンドを作成し、実行する
    
    // TODO: 各コマンド実行の結果を出力する
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Rustオンラインコンパイラ