Debug 트레이트
Coddy Rust 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 61개 중 35번째.
Rust의 표준 라이브러리는 공통 기능을 제공하는 미리 정의된 많은 트레이트들을 포함하고 있습니다. 개발에 가장 유용한 것 중 하나는 Debug 트레이트로, 구조체의 내용을 검사하기 위해 출력할 수 있게 해줍니다.
사용자 정의 구조체를 직접 출력하려고 하면, Rust는 이를 어떻게 표시해야 할지 알지 못합니다:
struct Player {
name: String,
score: u32,
}
let p = Player { name: String::from("Alice"), score: 100 };
println!("{:?}", p); // 오류! Debug가 구현되지 않음
{:?} 포매터는 Debug 트레이트가 필요합니다. 수동으로 구현하는 대신, Rust는 #[derive] 속성이라는 지름길을 제공합니다. 구조체 정의 바로 위에 배치하세요:
#[derive(Debug)]
struct Player {
name: String,
score: u32,
}
let p = Player { name: String::from("Alice"), score: 100 };
println!("{:?}", p); // Player { name: "Alice", score: 100 }
#[derive(Debug)] 속성은 컴파일러에게 Debug 구현을 자동으로 생성하도록 지시합니다. 이는 구조체의 모든 필드가 Debug를 구현하고 있는 한 작동합니다 (대부분의 표준 타입들이 그러합니다).
중첩된 구조를 더 읽기 쉬운 출력으로 보려면, {:#?}를 사용하여 예쁘게 출력(pretty-printing)하세요:
println!("{:#?}", p);
// Player {
// name: "Alice",
// score: 100,
// }
Debug를 파생(Deriving)하는 것은 개발 중에 필수적입니다. 이를 통해 사용자 정의 포맷팅 코드를 작성하지 않고도 데이터를 빠르게 검사할 수 있습니다.
챌린지
쉬움Debug 트레이트를 파생(derive)하여 구조체를 검사 가능하게 만들어 봅시다! 디버깅 목적으로 아이템을 출력할 수 있는 간단한 인벤토리 시스템을 만들게 됩니다.
코드는 두 개의 파일로 구성됩니다:
inventory.rs: 두 개의 공개 필드name(String)과quantity(u32)를 가진 공개Item구조체를 정의하세요.#[derive(Debug)]속성을 사용하여 구조체에 Debug 트레이트를 자동으로 구현하세요.main.rs: 인벤토리 모듈을 가져오고 제공된 입력을 사용하여Item인스턴스를 생성하세요. 디버그 포맷터{:?}를 사용하여 아이템을 출력하고 내부 구조를 표시하세요.
Debug를 파생하는 것의 장점은 Rust가 자동으로 포맷팅 코드를 생성해 준다는 것입니다. 수동으로 구현할 필요가 없습니다! 구조체에 속성만 추가하면 {:?}로 출력이 가능해집니다.
출력은 Rust의 디버그 형식으로 표시되어야 합니다:
Item { name: "{name}", quantity: {quantity} }예를 들어, 입력값이 Keyboard와 15인 경우:
Item { name: "Keyboard", quantity: 15 }두 개의 입력을 받게 됩니다: 아이템 이름과 수량(u32로 파싱).
치트 시트
Debug 트레이트는 {:?} 포매터를 사용하여 검사를 위해 구조체의 내용을 출력할 수 있게 해줍니다.
#[derive(Debug)] 속성을 사용하여 구조체에 대해 자동으로 Debug를 구현하세요:
#[derive(Debug)]
struct Player {
name: String,
score: u32,
}
let p = Player { name: String::from("Alice"), score: 100 };
println!("{:?}", p); // Player { name: "Alice", score: 100 }
더 나은 서식의 예쁜 출력(pretty-printed output)을 위해 {:#?}를 사용하세요:
println!("{:#?}", p);
// Player {
// name: "Alice",
// score: 100,
// }
#[derive(Debug)] 속성은 구조체의 모든 필드가 Debug를 구현하고 있는 한 작동하며, 대부분의 표준 타입들이 이를 구현하고 있습니다.
직접 해보기
mod inventory;
use inventory::Item;
fn main() {
// 입력 읽기
let mut name = String::new();
std::io::stdin().read_line(&mut name).expect("Failed to read line");
let name = name.trim().to_string();
let mut quantity_str = String::new();
std::io::stdin().read_line(&mut quantity_str).expect("Failed to read line");
let quantity: u32 = quantity_str.trim().parse().expect("Failed to parse quantity");
// TODO: 주어진 이름과 수량으로 Item 인스턴스 생성
// TODO: 디버그 포맷터 {:?}를 사용하여 아이템 출력
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.