디버그
std::fmt의 형식 지정자를 사용하려면 출력할 자료형마다 해당 기능을 구현해야 합니다.
표준(std) 라이브러리의 자료형들에 대해서는 이미 구현이 되어 있지만,
다른 자료형의 경우에는 반드시 직접 구현해야만 합니다.
이때 fmt::Debug 를 이용하면 어렵지 않게 만들 수 있습니다.
어떤 자료형이든 fmt::Debug 을 이용해 파생 구현(derive)을 할 수 있습니다.
#![allow(unused)]
fn main() {
// 아래 구조체는 fmt::Display 나 fmt::Debug 중 어느것으로도 출력할 수 없습니다.
struct UnPrintable(i32);
// derive 속성을 사용하면 fmt::Debug 으로 구조체를 출력할 수 있는 코드가 구현됩니다.
#[derive(Debug)]
struct DebugPrintable(i32);
}
또한 모든 표준(std) 라이브러리의 자료형들은 {:?} 으로 출력이 가능합니다.
// Structure 구조체를 위해 fmt::Debug를 파생 구현합니다.
// 이 구조체는 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 는 출력 기능은 제공하지만, 우아함은 포기해야합니다.
러스트에는 {:#?}를 이용한 “예쁘게 출력하기” 기능도 있습니다.
#[derive(Debug)]
struct Person<'a> {
name: &'a str,
age: u8
}
fn main() {
let name = "Peter";
let age = 27;
let peter = Person { name, age };
// 예쁘게 출력하기
println!("{:#?}", peter);
}
출력 형식을 바꾸려면 fmt::Display 를 직접 구현해야만 합니다.