가변 메서드
Coddy Rust 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 61개 중 3번째.
때때로 메서드는 단순히 데이터를 읽는 것 이상의 작업을 수행해야 합니다. 즉, 데이터를 변경해야 할 때가 있습니다. 구조체의 필드를 수정할 수 있는 메서드를 만들려면, &self 대신 &mut self를 사용합니다.
mut 키워드는 가변 빌림(mutable borrow)을 나타내며, 메서드에 인스턴스의 내부 상태를 변경할 수 있는 권한을 부여합니다:
struct Counter {
value: i32,
}
impl Counter {
fn increment(&mut self) {
self.value += 1;
}
fn decrement(&mut self) {
self.value -= 1;
}
fn get(&self) -> i32 {
self.value
}
}
increment와 decrement는 value를 수정하기 때문에 &mut self를 사용하고, get은 데이터를 읽기만 하기 때문에 &self를 사용한다는 점에 유의하세요.
가변 메서드를 호출할 때, 인스턴스 자체도 가변으로 선언되어야 합니다:
fn main() {
let mut counter = Counter { value: 0 };
counter.increment();
counter.increment();
println!("{}", counter.get()); // 2
counter.decrement();
println!("{}", counter.get()); // 1
}
인스턴스를 생성할 때 mut 키워드를 잊어버리면, Rust는 해당 인스턴스에서 어떠한 &mut self 메서드도 호출하지 못하도록 방지합니다. 이를 통해 데이터가 변경될 수 있는 시점을 항상 인지할 수 있습니다.
챌린지
쉬움단일 필드 balance (i32)를 가진 BankAccount 구조체를 생성하세요.
BankAccount에 대해 다음 세 가지 메서드를 포함하는 구현(implementation) 블록을 추가하세요:
deposit—&mut self와amount: i32를 매개변수로 받아, 잔액(balance)에 해당 금액을 더합니다.withdraw—&mut self와amount: i32를 매개변수로 받아, 잔액(balance)에서 해당 금액을 뺍니다.get_balance—&self를 매개변수로 받아 현재 잔액을i32로 반환합니다.
세 개의 입력을 받게 됩니다:
- 첫 번째 줄: 초기 잔액 (i32)
- 두 번째 줄: 입금액 (i32)
- 세 번째 줄: 출금액 (i32)
초기 잔액으로 가변(mutable) BankAccount 인스턴스를 생성한 후, 주어진 금액을 입금하고, 주어진 금액을 출금한 다음, 최종 잔액을 출력하세요.
예상 출력 형식:
{final_balance}치트 시트
구조체 필드를 수정하는 메서드는 &mut self(가변 빌림)를 사용하고, 데이터를 읽기만 하는 메서드는 &self를 사용합니다:
struct Counter {
value: i32,
}
impl Counter {
fn increment(&mut self) {
self.value += 1;
}
fn decrement(&mut self) {
self.value -= 1;
}
fn get(&self) -> i32 {
self.value
}
}
가변 메서드를 호출하려면 인스턴스가 let mut을 사용하여 가변으로 선언되어야 합니다:
let mut counter = Counter { value: 0 };
counter.increment();
counter.increment();
println!("{}", counter.get()); // 2
counter.decrement();
println!("{}", counter.get()); // 1
인스턴스에 mut 키워드가 없으면, Rust는 어떠한 &mut self 메서드의 호출도 방지합니다.
직접 해보기
use std::io;
// TODO: 여기에 BankAccount 구조체를 정의하세요
// TODO: deposit, withdraw, get_balance 메서드를 포함하는 BankAccount의 구현 블록을 추가하세요
fn main() {
let mut input = String::new();
// 초기 잔액 읽기
io::stdin().read_line(&mut input).expect("Failed to read line");
let initial_balance: i32 = input.trim().parse().expect("Invalid number");
input.clear();
// 입금액 읽기
io::stdin().read_line(&mut input).expect("Failed to read line");
let deposit_amount: i32 = input.trim().parse().expect("Invalid number");
input.clear();
// 출금액 읽기
io::stdin().read_line(&mut input).expect("Failed to read line");
let withdraw_amount: i32 = input.trim().parse().expect("Invalid number");
// TODO: initial_balance를 사용하여 가변 BankAccount 인스턴스를 생성하세요
// TODO: deposit_amount로 deposit을 호출하세요
// TODO: withdraw_amount로 withdraw를 호출하세요
// TODO: get_balance를 사용하여 최종 잔액을 출력하세요
}이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.