🎯

Enum과 패턴 매칭 — Symbol과 case/when의 강력한 진화판

Rust의 enum은 데이터를 담을 수 있다 — Ruby에는 없는 개념

Ruby에서 상태를 표현할 때 Symbol을 쓴다. :active, :inactive, :pending. Rust의 enum이 이 역할을 한다.

enum Status {
    Active,
    Inactive,
    Pending,
}

let s = Status::Active;

여기까지는 Ruby의 Symbol과 비슷하다. 근데 Rust enum의 진짜 힘은 각 변형에 데이터를 담을 수 있다는 것이다.

데이터를 담는 enum

enum Message {
    Quit,                       // 데이터 없음
    Text(String),               // String 하나
    Move { x: i32, y: i32 },    // 이름 있는 필드
    Color(u8, u8, u8),          // 여러 값
}

let msg = Message::Text(String::from("hello"));
let pos = Message::Move { x: 10, y: 20 };

Ruby에서 이걸 하려면 클래스 상속이나 Hash를 써야 한다. Rust에서는 enum 하나로 "이 타입은 이런 형태들 중 하나다"를 표현한다.

match — 강제 완전 매칭

Ruby의 case/when에 대응하지만, 모든 경우를 처리해야 한다.

# Ruby — else 없어도 OK
case status
when :active then "활성"
when :inactive then "비활성"
# :pending을 빠뜨려도 에러 없음
end

// Rust — 빠뜨리면 컴파일 에러
match status {
    Status::Active => "활성",
    Status::Inactive => "비활성",
    Status::Pending => "대기",  // 빠뜨리면 error[E0004]
}

이게 왜 좋은가? 나중에 enum에 새 변형을 추가하면, match를 쓴 모든 곳에서 컴파일 에러가 난다. 처리 안 한 케이스를 절대 놓치지 않는다.

match에서 데이터 추출

match msg {
    Message::Quit => println!("종료"),
    Message::Text(text) => println!("텍스트: {}", text),
    Message::Move { x, y } => println!("이동: ({}, {})", x, y),
    Message::Color(r, g, b) => println!("색: {},{},{}", r, g, b),
}

enum 안에 담긴 데이터를 꺼내면서 동시에 분기한다. Ruby에서 case/when으로 타입 체크하고 데이터를 꺼내는 걸 한 번에 하는 셈.

if let — 하나만 체크할 때

match가 모든 경우를 처리하는 반면, 하나만 확인하고 싶을 때는 if let을 쓴다.

if let Message::Text(text) = msg {
    println!("텍스트: {}", text);
}
// 나머지는 무시

Ruby의 if status == :active 같은 느낌인데, 데이터 추출까지 동시에 한다.

Option과 Result도 enum이다

Option<T>Some(T) 또는 None, Result<T, E>Ok(T) 또는 Err(E). 둘 다 enum이다. Rust의 에러 처리가 enum 위에 세워져 있다는 뜻이다.

핵심 포인트

1

enum은 Ruby의 Symbol 그룹 + 데이터를 담을 수 있는 진화판

2

match는 case/when의 강화판 — 모든 케이스를 빠짐없이 처리

3

match에서 데이터 추출과 분기를 동시에 한다

4

Option, Result도 enum — Rust 에러 처리의 기반

장점

  • enum에 변형을 추가하면 처리 안 한 곳을 컴파일러가 전부 찾아준다
  • 데이터를 담는 enum은 Ruby의 클래스 상속보다 간결하다

단점

  • Ruby의 Symbol처럼 가볍게 쓰기엔 보일러플레이트가 많다
  • match의 강제 완전 매칭이 처음엔 귀찮게 느껴진다

사용 사례

상태 머신 — 주문 상태(대기/처리중/완료/취소)를 타입으로 표현 API 응답 — 성공/에러/타임아웃 각각에 다른 데이터를 담을 때