Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

テストケース: List

要素をそれぞれ順番に処理しなければならない構造体に対して fmt::Display を実装するのは厄介です。問題は、それぞれの write!fmt::Result を生成することです。これを適切に処理するには、_すべて_の結果を扱う必要があります。Rust はまさにこの目的のために ? 演算子を提供しています。

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 {
        // `List` 構造体に格納されている Vec<i32> への参照を作成する。
        let vec = &self.0;

        write!(f, "[")?;

        // 反復のインデックスを `index` として列挙しながら、
        // `vec` 内の `v` を反復処理する。
        for (index, v) in vec.iter().enumerate() {
            // 最初の要素を除くすべての要素に、カンマを追加する。
            // エラー時に return するために ? 演算子を使う。
            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]

関連項目:

forrefResultstruct?、および vec!