Step 02: 열거형과 패턴 매칭
foundations 60 min

열거형과 패턴 매칭

enum으로 책 상태를 표현하고 match로 패턴 매칭합니다.

Execute this step

Run from project root:
cargo run

Step 2: 열거형과 패턴 매칭

학습 목표

  • 열거형으로 여러 상태를 안전하게 표현하기
  • match 표현식으로 모든 경우를 처리하기
  • 열거형에 데이터를 포함시키기

핵심 개념

1. 기본 열거형

1enum Category {
2    Fiction,      // 소설
3    NonFiction,   // 비소설
4    Science,      // 과학
5    History,      // 역사
6}

2. 데이터를 포함하는 열거형

Rust의 열거형은 각 variant가 데이터를 가질 수 있습니다!

1enum BookStatus {
2    Available,
3    Borrowed { 
4        by: String,      // 대여자
5        due_date: String // 반납 예정일
6    },
7    Reserved { 
8        by: String       // 예약자
9    },
10    Lost,
11}

3. match 패턴 매칭

match는 모든 경우를 반드시 처리해야 합니다 (exhaustive).

1match book.status {
2    BookStatus::Available => {
3        println!("대여 가능");
4    }
5    BookStatus::Borrowed { by, due_date } => {
6        println!("대여 중: {} (반납일: {})", by, due_date);
7    }
8    BookStatus::Reserved { by } => {
9        println!("예약됨: {}", by);
10    }
11    BookStatus::Lost => {
12        println!("분실");
13    }
14}

4. 와일드카드 패턴

1match book.status {
2    BookStatus::Available => {
3        // 대여 가능한 경우만 처리
4    }
5    _ => {
6        // 나머지 모든 경우
7        println!("대여 불가");
8    }
9}

소스 코드

1#[derive(Debug)] // Debug 트레이트 자동 구현
2enum Category {
3    Fiction,
4    NonFiction,
5    Science,
6    History,
7}
8
9enum BookStatus {
10    Available,
11    Borrowed { by: String, due_date: String },
12    Reserved { by: String },
13    Lost,
14}
15
16struct Book {
17    id: u32,
18    title: String,
19    author: String,
20    status: BookStatus,
21    category: Category,
22}
23
24impl Book {
25    fn new(id: u32, title: String, author: String, category: Category) -> Book {
26        Book {
27            id,
28            title,
29            author,
30            status: BookStatus::Available,
31            category,
32        }
33    }
34    
35    fn display(&self) {
36        print!("[{}] {} - {} ", self.id, self.title, self.author);
37        
38        // match로 상태 출력
39        match &self.status {
40            BookStatus::Available => println!("(대여 가능)"),
41            BookStatus::Borrowed { by, due_date } => {
42                println!("(대여 중: {} - 반납일: {})", by, due_date)
43            }
44            BookStatus::Reserved { by } => println!("(예약됨: {})", by),
45            BookStatus::Lost => println!("(분실)"),
46        }
47    }
48    
49    fn borrow_book(&mut self, borrower: String, due_date: String) -> bool {
50        match self.status {
51            BookStatus::Available => {
52                self.status = BookStatus::Borrowed { 
53                    by: borrower.clone(), 
54                    due_date: due_date.clone() 
55                };
56                println!("✓ '{}'을(를) {}님이 대여했습니다.", self.title, borrower);
57                true
58            }
59            _ => {
60                println!("✗ '{}'은(는) 대여할 수 없습니다.", self.title);
61                false
62            }
63        }
64    }
65    
66    fn return_book(&mut self) -> bool {
67        match self.status {
68            BookStatus::Borrowed { .. } => {
69                self.status = BookStatus::Available;
70                println!("✓ '{}' 반납 완료!", self.title);
71                true
72            }
73            _ => {
74                println!("✗ '{}' 대여 중이 아닙니다.", self.title);
75                false
76            }
77        }
78    }
79    
80    fn get_category_name(&self) -> &str {
81        match self.category {
82            Category::Fiction => "소설",
83            Category::NonFiction => "비소설",
84            Category::Science => "과학",
85            Category::History => "역사",
86        }
87    }
88}
89
90fn main() {
91    println!("=== 도서 관리 시스템 v0.3 ===\n");
92    
93    let mut book1 = Book::new(
94        1,
95        String::from("러스트 프로그래밍"),
96        String::from("스티브"),
97        Category::Science,
98    );
99    
100    let mut book2 = Book::new(
101        2,
102        String::from("해리포터"),
103        String::from("J.K. 롤링"),
104        Category::Fiction,
105    );
106    
107    println!("카테고리: {}", book1.get_category_name());
108    book1.display();
109    
110    println!();
111    
112    book1.borrow_book(String::from("김철수"), String::from("2026-02-20"));
113    book1.display();
114    
115    println!();
116    
117    book1.borrow_book(String::from("이영희"), String::from("2026-02-25"));
118    
119    println!();
120    
121    book1.return_book();
122    book1.display();
123    
124    println!("\n카테고리: {}", book2.get_category_name());
125    book2.display();
126}

실행 결과

1=== 도서 관리 시스템 v0.3 ===
2
3카테고리: 과학
4[1] 러스트 프로그래밍 - 스티브 (대여 가능)
5
6✓ '러스트 프로그래밍'을(를) 김철수님이 대여했습니다.
7[1] 러스트 프로그래밍 - 스티브 (대여 중: 김철수 - 반납일: 2026-02-20)
8
9✗ '러스트 프로그래밍'은(는) 대여할 수 없습니다.
10
11✓ '러스트 프로그래밍' 반납 완료!
12[1] 러스트 프로그래밍 - 스티브 (대여 가능)
13
14카테고리: 소설
15[2] 해리포터 - J.K. 롤링 (대여 가능)

체크리스트

  • [ ] 열거형을 정의하고 사용했습니다
  • [ ] 데이터를 포함하는 열거형을 만들었습니다
  • [ ] match로 모든 경우를 처리했습니다
  • [ ] 와일드카드 패턴(_)을 사용했습니다
  • [ ] 패턴으로 열거형의 데이터를 분해했습니다

다음 단계

Step 3에서는 Option과 Result를 배워서 에러를 안전하게 처리합니다.

Did you find this helpful? Give it a cheer!