데이터 배리언트 매칭
Coddy Rust 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 61개 중 16번째.
이전 레슨에서는 다양한 변형을 처리하기 위해 enum 메서드 안에서 match를 사용했습니다. 이제 match가 이러한 변형 안에 저장된 데이터를 실제로 추출하는 방법, 즉 destructure라는 기법에 집중해 보겠습니다.
데이터를 holds하는 enum variant에 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);
}
}
}
각 arm은 variant의 구조에 따라 데이터를 서로 다르게 추출합니다. 구조체와 유사한 variant의 경우 { field_name }을 사용하여 named 필드를 꺼냅니다. 튜플 variant의 경우 (width, height)와 같은 위치 변수를 사용합니다.
선택한 변수 이름은 해당 match 분기 안에서 사용할 수 있게 됩니다. 이는 현재 어떤 변형인지 확인하는 동시에 그 페이로드에 접근할 수 있기 때문에 강력합니다.
컴파일러는 모든 변형을 handle하도록 보장하며, 추출된 값은 즉시 사용할 준비가 됩니다. 추가 steps가 필요하지 않습니다.
챌린지
쉬움다양한 유형의 사용자 명령을 처리하는 command processor를 만들어 봅시다. 각 command는 서로 다른 데이터를 포함하며, processor는 pattern matching을 사용해 해당 데이터를 추출하고 appropriate 응답을 생성합니다.
코드를 구성하기 위해 두 개의 파일을 만듭니다:
command.rs: 세 가지 variant를 가진 publicCommandenum을 Define합니다:Say: singleStringmessage를 포함합니다(tuple syntax).Move: named fields인direction(String)과steps(u32)를 포함합니다.Calculate: 더할 숫자를 나타내는 두 개의i32값을 포함합니다(tuple syntax).
match를 사용해 각 variant를 destructure하고 수행한 동작을 설명하는String을 return하는executemethod를 Implement합니다.main.rs: command module을 가져오고, 제공된 inputs를 사용해 각 command variant의 인스턴스를 하나씩 만든 다음 각 인스턴스에서executemethod를 호출해 results를 출력합니다.
execute method는 각 variant를 destructure하여 해당 데이터에 접근하고, 다음의 exact formats로 messages를 return해야 합니다:
Say의 경우:Saying: {message}Move의 경우:Moving {steps} steps {direction}Calculate의 경우:{a} + {b} = {sum}
출력에는 각 command의 결과가 각각 별도의 line에 표시되어야 합니다:
Saying: {message}
Moving {steps} steps {direction}
{a} + {b} = {sum}예를 들어, say message가 "Hello world"이고, 5 steps만큼 "north"로 Move하며, 10과 25를 Calculate하는 경우 출력은 다음과 같습니다:
Saying: Hello world
Moving 5 steps north
10 + 25 = 35다섯 개의 inputs를 받습니다: say message, direction, steps의 number, 그리고 Calculate할 두 number입니다.
REQUIRED OUTPUT FORMAT:직접 해보기
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: 각 명령 실행 결과를 출력하세요
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 Rust 컴파일러