Menu
Coddy logo textTech

데이터 배리언트 매칭

Coddy Rust 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 61개 중 16번째.

이전 레슨에서 여러분은 다양한 변형(variants)을 처리하기 위해 열거형(enum) 메서드 내부에서 match를 사용했습니다. 이제 match가 실제로 해당 변형 내부에 저장된 데이터를 어떻게 추출하는지에 집중해 보겠습니다. 이 기술을 구조 분해(destructuring)라고 합니다.

데이터를 보유한 열거형 변형(enum variant)에 대해 매칭할 때, 패턴 내에서 해당 데이터를 변수에 바로 바인딩할 수 있습니다:

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);
        }
    }
}

각 암(arm)은 배리언트의 구조에 따라 데이터를 다르게 추출합니다. 구조체 형태의 배리언트의 경우, { field_name }을 사용하여 이름이 있는 필드를 추출합니다. 튜플 형태의 배리언트의 경우, (width, height)와 같은 위치 기반 변수를 사용합니다.

선택한 변수 이름은 해당 매치 암(match arm) 내부에서 사용할 수 있게 됩니다. 이는 어떤 배리언트(variant)인지 확인하는 것과 동시에 그 페이로드(payload)에 접근할 수 있기 때문에 매우 강력합니다.

컴파일러는 모든 변형(variant)을 처리하도록 보장하며, 추출된 값은 즉시 사용할 수 있어 별도의 단계가 필요하지 않습니다.

challenge icon

챌린지

쉬움

다양한 유형의 사용자 명령을 처리하는 명령 프로세서를 만들어 보겠습니다. 각 명령은 서로 다른 데이터를 포함하며, 프로세서는 패턴 매칭을 사용하여 해당 데이터를 추출하고 적절한 응답을 생성합니다.

코드를 구성하기 위해 두 개의 파일을 생성합니다:

  • command.rs: 세 가지 변리언트(variant)를 가진 공개 Command 열거형(enum)을 정의합니다:
    • Say — 단일 String 메시지를 보유합니다 (튜플 구문)
    • Move — 이름이 있는 필드인 direction (String)과 steps (u32)를 보유합니다
    • Calculate — 더할 숫자를 나타내는 두 개의 i32 값을 보유합니다 (튜플 구문)
    그런 다음 match를 사용하여 각 변리언트를 구조 분해(destructure)하고 수행된 작업을 설명하는 String을 반환하는 execute 메서드를 구현합니다.
  • main.rs: 명령 모듈을 가져오고, 제공된 입력을 사용하여 각 명령 변리언트의 인스턴스를 하나씩 생성한 다음, 각각에 대해 execute 메서드를 호출하여 결과를 출력합니다.

execute 메서드는 각 변리언트를 구조 분해하여 데이터에 접근하고, 정확히 다음 형식으로 메시지를 반환해야 합니다:

  • Say의 경우: Saying: {message}
  • Move의 경우: Moving {steps} steps {direction}
  • Calculate의 경우: {a} + {b} = {sum}

출력은 각 명령의 결과를 별도의 줄에 표시해야 합니다:

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

예를 들어, say 메시지가 "Hello world"이고, "north" 방향으로 5 steps 이동하며, 1025를 계산하는 경우 출력은 다음과 같습니다:

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

say 메시지, 방향(direction), 걸음 수(steps), 그리고 계산할 두 개의 숫자까지 총 다섯 개의 입력을 받게 됩니다.

치트 시트

match를 사용한 패턴 매칭을 통해 열거형(enum) 변형을 구조 분해하고 해당 데이터를 패턴에서 직접 추출할 수 있습니다.

튜플 변형(tuple variants)의 경우, 위치 기반 변수를 사용합니다:

enum Event {
    KeyPress(char),
    Resize(u32, u32),
}

match event {
    Event::KeyPress(key) => {
        println!("Key: {}", key);
    }
    Event::Resize(width, height) => {
        println!("{}x{}", width, height);
    }
}

구조체형 변형(struct-like variants)의 경우, 이름이 지정된 필드 구문을 사용합니다:

enum Event {
    Click { x: i32, y: i32 },
}

match event {
    Event::Click { x, y } => {
        println!("Clicked at ({}, {})", x, y);
    }
}

추출된 변수는 각각의 match arm 내에서 사용할 수 있게 되며, 이를 통해 변형 타입을 확인하는 동시에 데이터에 접근할 수 있습니다.

직접 해보기

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실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

Object Oriented Programming의 모든 레슨