println! デバッグ
ターミナルに結果を出力して内容が期待するものか確認するデバッグです。これにはprintln!
、またはeprintln!
マクロを使います。これらはstdout
かstderr
に出力するかの違いがあります。
println!("foo");
eprintln!("foo");
Trait std::fmt::Display を持っていれば{}
を含めることで、変数をその位置に埋め込んで出力できます。
例えばstr
はDisplay
を持っているので以下のように使えます。
println!("hello {}", "world!");
// hello world!
{}
が複数ある場合は、後の引数にその数だけDisplay
を持つ値を与えてあげる必要があります。
println!(
"My favorite fruits: {}, {}, {}",
"apple", "tangerines", "peaches"
);
Display
からfmt
を実装すれば適用な Struct インスタンスを{}
に渡して表示できるようになります。
struct Foo;
impl std::fmt::Display for Foo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Foo")
}
}
fn main() {
println!("{}", Foo);
// Foo
}
Display
に似たトレイトに Trait std::fmt::Debug があります。これは開発者向けの結果を出力する為に使います。
この出力には{}
の代わりに{:?}
を使います。例えばstr
はDebug
も持っているのでこう書いても大丈夫です。
println!("hello {:?}", "world!");
// hello world!
Debug
もDisplay
のようにfmt
を実装すれば、好きなように出力結果を調整できますが、こちらはderive
属性からすぐに最低限の形の実装を持たせることができます。
#[derive(Debug)]
struct Foo {
value: String
}
fn main() {
println!(
"foo is {:?}",
Foo {
value: "value".into()
}
);
}
// foo is Foo { value: "value" }
Struct のプロパティが多いと一行では見づらくなってきますが、そんな時用にプリティプリントが用意されてます。これは変わりに{:#?}
と置きます。
println!(
"foo is {:#?}",
Foo {
value: "value".into()
}
);
// foo is Foo {
// value: "value",
// }
順番の調整
順番を調整したい時は、{0}
または{1:?}
のように「0番目の値はここ、1番目の値はここ…」のように指定できます。
println!(
"{1} {0:?}",
Foo {
value: "value".into()
},
"###"
)
// ### Foo { value: "value" }
また数値だけではなく名前を付けて「foo
はここ、bar
はここ」ということもできます。それには、{foo:?}
や{bar}
のように中にその名前を置き、引数はfoo = Foo { ... }
のような形で渡します。
println!(
"{foo:?} {bar}",
foo = Foo {
value: "value".into()
},
bar = "bar"
)
// Foo { value: "value" } bar