Читаем Rust на примерах полностью

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Можно вручную реализовать fmt::Display для управления отображением.

<p id="Смотрите_также_2"><strong><a l:href="#Смотрите_также_2">Смотрите также:</a></strong></p>

attributes, derive, std::fmt, и struct

<p id="display"><strong><a l:href="#display">Display</a></strong></p>

fmt::Debug выглядит не очень компактно и красиво, поэтому полезно настраивать внешний вид информации, которая будет напечатана. Это можно сделать реализовав типаж fmt::Display вручную, который использует маркер {} для печати. Его реализация выглядит следующим образом:

#![allow(unused)]

fn main() {

// Импортируем (с помощью `use`) модуль `fmt`, чтобы мы могли его использовать.

use std::fmt;

// Определяем структуру, для которой будет реализован `fmt::Display`.

// Это простая кортежная структура c именем `Structure`, которая хранит в себе `i32`.

struct Structure(i32);

// Чтобы была возможность использовать маркер `{}`

// `типаж (trait) fmt::Display` должен быть реализован вручную

// для данного типа.

impl fmt::Display for Structure {

// Этот типаж требует реализацию метода `fmt` с данной сигнатурой:

fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

// Записываем первый элемент в предоставленный выходной поток: `f`.

// Возвращаем `fmt::Result`, который показывает выполнилась операция

// успешно или нет. Обратите внимание на то, что синтаксис `write!`

// похож на синтаксис `println!`.

write!(f, "{}", self.0)

}

}

}

Вывод fmt::Display может быть более чистым, чем fmt::Debug, но может быть проблемой для стандартной библиотеки (std). Как нестандартные типы должны отображаться? Например, если std предоставляет единый стиль вывода для Vec, каким этот вывод должен быть? Любой из этих двух?

   • Vec: /:/etc:/home/username:/bin (разделитель :)

   • Vec: 1,2,3 (разделитель ,)

Нет, потому что не существует идеального стиля вывода для всех типов, поэтому std не может его предоставить. fmt::Display не реализован для Vec или для других обобщённых контейнеров. Для этих случаев подойдёт fmt::Debug.

Это не проблема, потому что для любых новых контейнеров, типы которых не обобщённые, может быть реализован fmt::Display.

use std::fmt; // Импортируем `fmt`

// Структура, которая хранит в себе два числа.

// Вывод типажа `Debug` добавлен для сравнения с `Display`.

#[derive(Debug)]

struct MinMax(i64, i64);

// Реализуем `Display` для `MinMax`.

impl fmt::Display for MinMax {

fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

// Используем `self.номер`, чтобы получить доступ к каждому полю структуры.

write!(f, "({}, {})", self.0, self.1)

}

}

// Объявим структуру с именованными полями, для сравнения

#[derive(Debug)]

struct Point2D {

x: f64,

y: f64,

}

// По аналогии, реализуем `Display` для Point2D

impl fmt::Display for Point2D {

fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

// Обращаться к полям структуры Point2D будет по имени

Похожие книги

Книги не найдены