Введение
В этом лабораторном задании мы реализуем fmt::Display для структуры List, которая содержит Vec в Rust. Задача заключается в последовательном обработке каждого элемента с использованием макроса write!, так как он генерирует fmt::Result, которое необходимо обработать правильно. Для этого мы можем использовать оператор ? для проверки, возвращает ли write! ошибку, и возвращать ее, если это так, в противном случае продолжать выполнение. Реализовав fmt::Display для List, мы можем перебирать элементы в векторе и выводить их в квадратных скобках, разделенных запятыми. Задача - модифицировать программу так, чтобы она также выводила индекс каждого элемента в векторе. Ожидаемый вывод после модификации: [0: 1, 1: 2, 2: 3].
Примечание: Если лабораторное задание не задает имя файла, вы можете использовать любое имя файла, которое хотите. Например, вы можете использовать
main.rs, скомпилировать и запустить его с помощьюrustc main.rs &&./main.
Тестовый случай: List
Реализация fmt::Display для структуры, где каждый элемент должен быть обработан последовательно, является сложной задачей. Проблема заключается в том, что каждый вызов write! генерирует fmt::Result. Правильная обработка этого требует обращения с всеми результатами. Для этого в Rust предусмотрен оператор ?.
Использование ? с write! выглядит так:
// Попытайтесь выполнить `write!` и проверить, не возникло ли ошибки.
// Если ошибка возникла, верните ее. В противном случае продолжайте.
write!(f, "{}", value)?;
С использованием ? реализация 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 {
// Извлекаем значение с использованием индексирования кортежа
// и создаем ссылку на `vec`.
let vec = &self.0;
write!(f, "[")?;
// Перебираем элементы `v` в `vec`, при этом нумеруя
// итерацию в `count`.
for (count, v) in vec.iter().enumerate() {
// Для каждого элемента, кроме первого, добавляем запятую.
// Используем оператор `?` для возврата при ошибках.
if count!= 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]
Резюме
Поздравляем! Вы завершили лабораторное задание Testcase: List. Вы можете практиковаться в других лабораторных заданиях в LabEx, чтобы улучшить свои навыки.