デバッグ

println! デバッグ

ターミナルに結果を出力して内容が期待するものか確認するデバッグです。これにはprintln!、またはeprintln!マクロを使います。これらはstdoutstderrに出力するかの違いがあります。

println!("foo");
eprintln!("foo");

Trait std::fmt::Display を持っていれば{}を含めることで、変数をその位置に埋め込んで出力できます。

例えばstrDisplayを持っているので以下のように使えます。

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 があります。これは開発者向けの結果を出力する為に使います。

この出力には{}の代わりに{:?}を使います。例えばstrDebugも持っているのでこう書いても大丈夫です。

println!("hello {:?}", "world!");
// hello world!

DebugDisplayのように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