Реализовать fmt::Display для структуры, в которой каждый элемент должен обрабатываться последовательно не так то просто. Проблема в том, что write! каждый раз возвращает fmt::Result.
Правильная обработка fmt::Result требует работы с каждым результатом.
Для подобных случаев Rust предоставляет макрос try!.
Использование try! для write! выглядит следующим образом:
// Попробуй исполнить `write!`, чтобы узнать, вернется ли ошибка. Если ошибка, верни ее.
// Если нет, то продолжи.
try!(write!(f, "{}", value));
С помощью макроса try! реализация fmt::Display для Vec довольно простая:
use std::fmt; // Импортируем модуль `fmt`.
// Определим структуру с именим `List`, которая хранит в себе `Vec`.
struct List(Vec<i32>);
impl fmt::Display for List {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Разыменуем `self` и создадим связь с `vec`
// с помощью ссылки.
let List(ref vec) = *self;
try!(write!(f, "["));
// Пройдемся по каждому `v` в `vec`.
// Номер итерации хранится в `count`.
for (count, v) in vec.iter().enumerate() {
// Для каждого элемента, кроме первого, добавим запятую
// до вызова `write!`. Используем `try!`, чтобы вернуться при наличие ошибок.
if count != 0 { try!(write!(f, ", ")); }
try!(write!(f, "{}", v));
}
// Закроем открытую скобку и вернем значение `fmt::Result`
write!(f, "]")
}
}
fn main() {
let v = List(vec![1, 2, 3]);
println!("{}", v);
}Попробуйте изменить программу так, чтобы индекс элемента так же выводился в консоль. Новый вывод должен выглядеть примерно вот так:
[0: 1, 1: 2, 2: 3]