다중 구현 블록
Coddy Rust 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 61개 중 5번째.
Rust에서는 구조체의 메서드들을 여러 개의 impl 블록으로 나눌 수 있습니다. 모든 내용을 하나의 블록에 넣을 수도 있지만, 이를 분리하면 코드를 더 체계적이고 가독성 있게 만들 수 있습니다.
여기에 기능이 두 개의 구현 블록으로 나뉜 구조체가 있습니다:
struct BankAccount {
balance: f64,
}
// 생성자 및 기본 조회
impl BankAccount {
fn new(initial: f64) -> BankAccount {
BankAccount { balance: initial }
}
fn balance(&self) -> f64 {
self.balance
}
}
// 트랜잭션 메서드
impl BankAccount {
fn deposit(&mut self, amount: f64) {
self.balance += amount;
}
fn withdraw(&mut self, amount: f64) {
self.balance -= amount;
}
}
두 블록은 원활하게 함께 작동하며, Rust는 이를 마치 하나인 것처럼 취급합니다. 어느 블록에 정의되어 있는지에 관계없이 모든 메서드를 호출할 수 있습니다:
fn main() {
let mut account = BankAccount::new(100.0);
account.deposit(50.0);
println!("{}", account.balance()); // 150
}
이 패턴은 구조체가 커질수록 특히 유용해집니다. 생성자들을 함께 그룹화하거나, 읽기 전용 메서드를 상태를 변경하는 메서드와 분리하여 유지하거나, 기능별로 정리할 수 있습니다. 하나의 구조체가 가질 수 있는 impl 블록의 수에는 제한이 없습니다.
챌린지
쉬움두 개의 필드 name (String)과 score (u32)를 가진 Player 구조체를 생성하세요.
구조체의 메서드들을 두 개의 별도 구현 블록(implementation blocks)으로 나누어 구성하세요:
첫 번째 impl 블록 — 생성자 및 조회:
new—name: String을 매개변수로 받아score가0으로 설정된Player를 반환하는 연관 함수get_score—&self를 매개변수로 받아 현재 점수를u32로 반환
두 번째 impl 블록 — 점수 수정:
add_points—&mut self와points: u32를 매개변수로 받아 점수에 해당 포인트를 추가reset_score—&mut self를 매개변수로 받아 점수를 다시0으로 설정
세 개의 입력을 받게 됩니다:
- 첫 번째 줄: 플레이어의 이름 (String)
- 두 번째 줄: 첫 번째 라운드에서 추가할 점수 (u32)
- 세 번째 줄: 두 번째 라운드에서 추가할 점수 (u32)
Player::new를 사용하여 플레이어를 생성하고, 첫 번째 라운드 점수를 추가한 후 점수를 출력하세요. 그런 다음 점수를 초기화(reset)하고, 두 번째 라운드 점수를 추가한 뒤 최종 점수를 출력하세요.
예상 출력 형식:
{score_after_first_round}
{score_after_reset_and_second_round}치트 시트
Rust는 더 나은 조직화를 위해 구조체의 메서드를 여러 impl 블록으로 나누는 것을 허용합니다:
struct BankAccount {
balance: f64,
}
// First impl block
impl BankAccount {
fn new(initial: f64) -> BankAccount {
BankAccount { balance: initial }
}
fn balance(&self) -> f64 {
self.balance
}
}
// Second impl block
impl BankAccount {
fn deposit(&mut self, amount: f64) {
self.balance += amount;
}
fn withdraw(&mut self, amount: f64) {
self.balance -= amount;
}
}
서로 다른 impl 블록에 있는 모든 메서드들은 원활하게 함께 작동합니다:
let mut account = BankAccount::new(100.0);
account.deposit(50.0);
println!("{}", account.balance()); // 150
구조체가 가질 수 있는 impl 블록의 수에는 제한이 없습니다. 이 패턴은 생성자와 상태를 변경하는 메서드를 분리하는 것과 같이 관련된 기능을 그룹화하는 데 유용합니다.
직접 해보기
use std::io;
// TODO: name (String)과 score (u32) 필드를 가진 Player 구조체를 정의하세요
// TODO: 첫 번째 impl 블록 - 생성자 및 조회 메서드 (new, get_score)
// TODO: 두 번째 impl 블록 - 점수 수정 메서드 (add_points, reset_score)
fn main() {
let mut input = String::new();
// 플레이어 이름 읽기
io::stdin().read_line(&mut input).expect("Failed to read line");
let name = input.trim().to_string();
// 첫 번째 라운드 점수 읽기
input.clear();
io::stdin().read_line(&mut input).expect("Failed to read line");
let first_round: u32 = input.trim().parse().expect("Invalid number");
// 두 번째 라운드 점수 읽기
input.clear();
io::stdin().read_line(&mut input).expect("Failed to read line");
let second_round: u32 = input.trim().parse().expect("Invalid number");
// TODO: Player::new를 사용하여 플레이어 생성
// TODO: 첫 번째 라운드 점수를 추가하고 점수 출력
// TODO: 점수 초기화
// TODO: 두 번째 라운드 점수를 추가하고 최종 점수 출력
}이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.