디버그
std::fmt 형식화 트레이트를 사용하려는 모든 타입은 출력 가능하도록 구현이 필요합니다. 자동 구현은 std 라이브러리와 같은 타입들에 대해서만 제공됩니다. 그 외의 모든 타입은 어떻게든 수동으로 구현_해야만_ 합니다.
fmt::Debug 트레이트는 이를 매우 간단하게 만들어 줍니다. 모든 타입은 fmt::Debug 구현을 derive(자동 생성)할 수 있습니다. 하지만 fmt::Display는 그렇지 않으며 수동으로 구현해야 합니다.
#![allow(unused)]
fn main() {
// 이 구조체는 `fmt::Display`나 `fmt::Debug` 중 어느 것으로도
// 출력할 수 없습니다.
struct UnPrintable(i32);
// `derive` 속성은 이 `구조체`를 `fmt::Debug`로 출력 가능하게 만드는 데
// 필요한 구현을 자동으로 생성합니다.
#[derive(Debug)]
struct DebugPrintable(i32);
}
모든 std 라이브러리 타입들도 {:?}로 자동 출력이 가능합니다:
// `Structure`에 대해 `fmt::Debug` 구현을 유도(derive)합니다. `Structure`는
// 단일 `i32`를 포함하는 구조체입니다.
#[derive(Debug)]
struct Structure(i32);
// `Deep` 구조체 안에 `Structure`를 넣으세요. 그리고 역시 출력 가능하게 만드세요.
#[derive(Debug)]
struct Deep(Structure);
fn main() {
// `{:?}`를 이용한 출력은 `{}`와 유사합니다.
println!("1년은 {:?}개월입니다.", 12);
println!("{1:?} {0:?}은 {actor:?}의 이름입니다.",
"슬레이터",
"크리스찬",
actor="배우의");
// `Structure`는 출력 가능합니다!
println!("이제 {:?}가 출력될 것입니다!", Structure(3));
// `derive`의 문제점은 결과가 어떻게 보일지 제어할 수 없다는 것입니다.
// 만약 이것을 단지 `7`로 보여주고 싶다면 어떡하죠?
println!("이제 {:?}가 출력될 것입니다!", Deep(Structure(7)));
}
따라서 fmt::Debug는 확실히 출력을 가능하게 하지만 우아함을 어느 정도 희생합니다. Rust는 {:#?}를 사용한 “예쁘게 출력하기(pretty printing)“도 제공합니다.
#[derive(Debug)]
struct Person<'a> {
name: &'a str,
age: u8
}
fn main() {
let name = "피터";
let age = 27;
let peter = Person { name, age };
// 예쁘게 출력하기
println!("{:#?}", peter);
}
fmt::Display를 수동으로 구현하여 출력을 제어할 수 있습니다.