Step 01: 구조체와 메서드
foundations 60 min

구조체와 메서드

Book 구조체를 정의하고 메서드를 구현합니다.

Execute this step

Run from project root:
cargo run

Step 1: 구조체와 메서드

학습 목표

  • 구조체로 복잡한 데이터를 표현하기
  • impl 블록으로 메서드 정의하기
  • &self와 &mut self의 차이 이해하기

핵심 개념

1. 구조체 정의

구조체는 관련된 데이터를 하나로 묶어주는 커스텀 타입입니다.

1struct Book {
2    id: u32,
3    title: String,
4    author: String,
5    available: bool,
6}

2. 구조체 생성

1fn main() {
2    let book = Book {
3        id: 1,
4        title: String::from("러스트 프로그래밍"),
5        author: String::from("스티브"),
6        available: true,
7    };
8    
9    println!("책 ID: {}", book.id);
10    println!("제목: {}", book.title);
11}

3. 메서드 구현

impl 블록 안에서 메서드를 정의합니다.

1impl Book {
2    // 연관 함수 (생성자)
3    fn new(id: u32, title: String, author: String) -> Book {
4        Book {
5            id,
6            title,
7            author,
8            available: true,
9        }
10    }
11    
12    // 불변 메서드 (&self)
13    fn display(&self) {
14        let status = if self.available { "대여 가능" } else { "대여 중" };
15        println!("[{}] {} - {} ({})", self.id, self.title, self.author, status);
16    }
17    
18    // 가변 메서드 (&mut self)
19    fn borrow_book(&mut self) -> bool {
20        if self.available {
21            self.available = false;
22            true
23        } else {
24            false
25        }
26    }
27    
28    fn return_book(&mut self) {
29        self.available = true;
30    }
31}

4. &self vs &mut self

  • &self: 불변 참조, 값을 읽기만 함
  • &mut self: 가변 참조, 값을 수정할 수 있음

소스 코드

전체 src/main.rs:

1struct Book {
2    id: u32,
3    title: String,
4    author: String,
5    available: bool,
6}
7
8impl Book {
9    fn new(id: u32, title: String, author: String) -> Book {
10        Book {
11            id,
12            title,
13            author,
14            available: true,
15        }
16    }
17    
18    fn display(&self) {
19        let status = if self.available { "대여 가능" } else { "대여 중" };
20        println!("[{}] {} - {} ({})", self.id, self.title, self.author, status);
21    }
22    
23    fn borrow_book(&mut self) -> bool {
24        if self.available {
25            self.available = false;
26            println!("✓ '{}' 대여 완료!", self.title);
27            true
28        } else {
29            println!("✗ '{}' 이미 대여 중입니다.", self.title);
30            false
31        }
32    }
33    
34    fn return_book(&mut self) {
35        self.available = true;
36        println!("✓ '{}' 반납 완료!", self.title);
37    }
38}
39
40fn main() {
41    println!("=== 도서 관리 시스템 v0.2 ===\n");
42    
43    // Book::new()는 연관 함수 (생성자)
44    let mut book = Book::new(
45        1,
46        String::from("러스트 프로그래밍"),
47        String::from("스티브"),
48    );
49    
50    // &self 메서드
51    book.display();
52    
53    println!();
54    
55    // &mut self 메서드
56    book.borrow_book();
57    book.display();
58    
59    println!();
60    
61    book.borrow_book(); // 이미 대여 중
62    
63    println!();
64    
65    book.return_book();
66    book.display();
67}

실행 결과

1=== 도서 관리 시스템 v0.2 ===
2
3[1] 러스트 프로그래밍 - 스티브 (대여 가능)
4
5✓ '러스트 프로그래밍' 대여 완료!
6[1] 러스트 프로그래밍 - 스티브 (대여 중)
7
8✗ '러스트 프로그래밍' 이미 대여 중입니다.
9
10✓ '러스트 프로그래밍' 반납 완료!
11[1] 러스트 프로그래밍 - 스티브 (대여 가능)

체크리스트

  • [ ] Book 구조체를 정의했습니다
  • [ ] impl 블록으로 메서드를 구현했습니다
  • [ ] &self와 &mut self의 차이를 이해했습니다
  • [ ] 연관 함수(생성자)를 만들었습니다
  • [ ] 가변 변수(mut)로 Book을 선언하고 수정했습니다

다음 단계

Step 2에서는 열거형(enum)과 패턴 매칭을 배워서 더 복잡한 상태를 표현합니다.

Did you find this helpful? Give it a cheer!