テストケース:リスト
構造体のそれぞれの要素を別々に扱うfmt::Displayを実装するのはトリッキーです。というのも、それぞれのwrite!が別々のfmt::Resultを生成するためです。適切に処理するためには すべての 結果に対して処理を書かなくてはなりません。このような場合は?演算子が使えます。
以下のように?をwrite!に対して使用します。
// `write!`を実行し、エラーが生じた場合はエラーを返します。そうでなければ実行を継続します。
write!(f, "{}", value)?;
?を使用すれば、Vec用のfmt::Displayはより簡単に実装できます。
use std::fmt; // `fmt`モジュールのインポート
// `Vec`を含む`List`という名の構造体を定義。
struct List(Vec<i32>);
impl fmt::Display for List {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// タプルインデックスを使って値を取り出し、それへの参照`vec`を作ります。
let vec = &self.0;
write!(f, "[")?;
// Iterate over `v` in `vec` while enumerating the iteration
// index in `index`.
for (index, v) in vec.iter().enumerate() {
// 先頭以外の全要素にカンマを付けます。
// ?演算子を使ってエラーを返します。
if index != 0 { write!(f, ", ")?; }
write!(f, "{}", v)?;
}
// 開きっぱなしのブラケットを閉じて、`fmt::Result`の値を返します。
write!(f, "]")
}
}
fn main() {
let v = List(vec![1, 2, 3]);
println!("{}", v);
}
演習
上記のプログラムを変更して、ベクタの各要素のインデックスも表示するようにしてみましょう。変更後の出力は次のようになります。
[0: 1, 1: 2, 2: 3]