飴屋

Rust/Formatter

fmt::Display トレイトのfmtメソッドを実装して、format!マクロとかで構造体を文字列で出力できるようにすることがよくあります。

struct TwoValues {
  one: f64,
  two: f64,
}
impl fmt::Display for TwoValues {
  fn fmt(&self,f:&mut fmt::Formatter)->fmt::Result {
    write!(f,"first one: {}, last one: {}",self.one,self.two)
  }
}

f64は桁数が大きくなることも多いので、文字列表現するときは小数点第三位くらいまででいいや、って思ったらそれができる記法が存在するそうなので使っています。

impl fmt::Display for TwoValues {
  fn fmt(&self,f:&mut fmt::Formatter)->fmt::Result {
    write!(f,"first one: {:.3}, last one: {:.3}",self.one,self.two)
  }
}

これがたまに小数点以下を全部出力したいときもあったりして、fmtメソッドを書き換えるのが面倒でした。

let val = TwoValues { one: 5.3, two: 1.0/3.0 };
println!("{}",val);
println!("{:.3}",val);

こんな感じで使うときに小数点以下を省略したりしなかったり、指定できればいいのにって思ってたら、fmtメソッドの引数についてくるfmt::Formatterを使ってできそうでした。

impl fmt::Display for TwoValues {
  fn fmt(&self,f:&mut fmt::Formatter)->fmt::Result {
    if let Some(precision) = f.precision() {
      write!(f,"first one: {:.*}, last one: {:.*}",precision,self.one,precision,self.two)
    } else {
      write!(f,"first one: {}, last one: {}",self.one,self.two)
    }
  }
}

符号をつけたりパッディングしたりいろいろ操作できたのを自分用にカスタマイズできるので便利に使いこなしたいぞ、 Formatter!