데이터를 포함하는 열거형(Variant Payloads)

좀더 복잡한 열거형의 경우 variant에 데이터(payload)를 포함시키도 합니다. 각 variant에 담긴 데이터는 match문을 이용해 추출합니다:

enum WebEvent {
    PageLoad,                 // Variant without payload
    KeyPress(char),           // Tuple struct variant
    Click { x: i64, y: i64 }, // Full struct variant
}

#[rustfmt::skip]
fn inspect(event: WebEvent) {
    match event {
        WebEvent::PageLoad       => println!("page loaded"),
        WebEvent::KeyPress(c)    => println!("pressed '{c}'"),
        WebEvent::Click { x, y } => println!("clicked at x={x}, y={y}"),
    }
}

fn main() {
    let load = WebEvent::PageLoad;
    let press = WebEvent::KeyPress('x');
    let click = WebEvent::Click { x: 20, y: 80 };

    inspect(load);
    inspect(press);
    inspect(click);
}
  • 열거형 안의 값은 패턴 매칭이 되고 난 이후에만 접근 가능합니다. 그 값에 대한 레퍼런스는 => 이후에 사용가능합니다.
    • 매치 패턴들은 위에서 아래로 순서에 따라 검사합니다. C나 C++에서와 같은 fall-through는 없습니다.
    • 매치 표현식 자체는 값을 가집니다. 그 값은 매칭이 된 패턴에서 가장 마지막에 수행된 표현식이 됩니다.
    • 가장 위에서 부터 어떤 패턴이 주어진 값과 매칭하는지 검사한 다음, 매칭된 것이 발견되면 화살표를 따라 코드를 수행합니다. 한 번 매칭이 되고 코드가 수행이 되면, 더이상의 매칭은 없습니다.
  • 매칭 패턴들이 불충분 하다면 어떤 일이 일어나는지 설명하세요. 러스트 컴파일러는 모든 가능한 케이스들이 핸들링 되는지 체크한다는 점을 상기시키세요.
  • match는 주어진 열거형 값이 실제로 어떤 variant인지 판단하기 위해, 그 variant의 종류가 기록된, 숨겨진 필드(식별자)의 값을 검사합니다.
  • std::mem::discriminant()를 이용하여 식별자를 얻을 수도 있습니다
    • 이는 각 필드 값을 굳이 비교할 필요 없는 구조체에 대해 PartialEq 트레잇을 구현할 때 유용합니다.
  • WebEvent::Click { ... }은 최상위 레벨 구조체 struct Click {...}를 따로 정의하고 WebEvent::Click(Click)처럼 튜플 형태로 정의한 것과 정확히 같진 않습니다. 예를 들어 WebEvent::Click { ... } 로 정의한 경우, 구조체 형태와 유사하지만 트레잇을 구현 할 수 없습니다.