// Данный макрос отобразит в консоли
// " 1". 5 пробелов и "1".
println!("{number:>width$}", number=1, width=6);
// Можно добавить к цифрам пару нулей. Данный макрос выведет "000001".
println!("{number:>0width$}", number=1, width=6);
// Компилятор обязательно проверит, что в макрос передано правильное количество
// аргументов.
println!("Меня зовут {0}, {1} {0}", "Бонд");
// ИСПРАВЬТЕ ^ Добавьте недостающий аргумент: "Джеймс"
// Создаём структуру, которая хранит в себе `i32`. Назовём её `Structure`.
#[allow(dead_code)]
struct Structure(i32);
// Однако, пользовательские типы данных, например, как эта структура
// требуют более сложной обработки для вывода. Данный код не будет работать.
println!("Эта структура `{}` не хочет выводится на экран...", Structure(3));
// ИСПРАВЬТЕ ^ Закомментируйте эту строку.
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
std::fmt содержит в себе много типажей, которые управляют отображением текста. Базовая форма двух самых важных рассмотрена ниже:
• fmt::Debug: Использует маркер {:?}. Форматирует текст для отладочных целей.
• fmt::Display: Использует маркер {}. Форматирует текст в более элегантном,удобном для пользователя стиле.
В данном примере используется fmt::Display, потому что стандартная библиотека предоставляет реализацию для данного типа. Для отображения собственных типов потребуется больше дополнительных шагов.
Реализация типажа fmt::Display автоматически предоставляет реализацию типажа ToString, который позволяет нам конвертировать наш тип в String.
Задания
• Исправьте две ошибки в коде выше (смотрите ИСПРАВЬТЕ), чтобы код компилировался без ошибок
• Добавьте макрос println!, который выводит: Pi is roughly 3.142 с помощью управления количеством знаков после запятой. Для выполнения данного задания создайте переменную, которая будет хранить в себе значение числа Пи: let pi = 3.141592. (Подсказка: вам необходимо ознакомиться с документацией по std::fmt, чтобы узнать, как отобразить в консоли только часть знаков после запятой).
Смотрите также:
std::fmt, макросы, struct, и trait
Debug
Все типы, которые будут использовать типажи форматирования std::fmt требуют их реализации для возможности печати. Автоматическая реализация предоставлена только для типов из стандартной библиотеки (std). Все остальные типы должны иметь собственную реализацию.
C помощью типажа fmt::Debug это сделать очень просто. Все типы могут выводить (автоматически создавать, derive) реализацию fmt::Debug. Сделать подобное с fmt::Display невозможно, он должен быть реализован вручную.
#![allow(unused)]
fn main() {
// Эта структура не может быть напечатана с помощью `fmt::Display`
// или с помощью `fmt::Debug`
struct UnPrintable(i32);
// Атрибут `derive` автоматически реализует
// необходимые методы, чтобы была возможность
// печатать данную `структуру` с помощью `fmt::Debug`.
#[derive(Debug)]
struct DebugPrintable(i32);
}
Все типы в стандартной библиотеке (std) могут быть напечатаны с {:?}:
// Вывод и реализация `fmt::Debug` для `Structure`.
// `Structure` - это структура, которая содержит в себе один `i32`.
#[derive(Debug)]
struct Structure(i32);
// Добавим структуру `Structure` в структуру `Deep`.
// Реализуем для `Deep` возможность вывода с помощью fmt::Debug`.
#[derive(Debug)]
struct Deep(Structure);
fn main() {
// Вывод с помощью `{:?}` аналогичен `{}`.
println!("{:?} месяцев в году.", 12);
println!("{1:?} {0:?} - это имя {actor:?}.",
"Слэйтер",
"Кристиан",
actor="актёра");
// `Structure` теперь можно напечатать!
println!("Теперь {:?} будет выведена на экран!", Structure(3));
// Проблема с `выводом (derive)`, в том, что у нас не будет контроля
// над тем, как будет выглядеть результат.
// Что если мы хотим напечатать просто `7`?
println!("А теперь напечатаем {:?}", Deep(Structure(7)));
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Так что fmt:: Debug определённо делает это для печати, но жертвует некоторыми изящество. Rust также обеспечивает "красивую печать" с помощью {:#?}.
#[derive(Debug)]
struct Person<'a> {
name: &'a str,
age: u8
}
fn main() {
let name = "Peter";
let age = 27;
let peter = Person { name, age };
// Pretty print
println!("{:#?}", peter);
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Можно вручную реализовать fmt::Display для управления отображением.
Смотрите также:
attributes, derive, std::fmt, и struct
Display
fmt::Debug выглядит не очень компактно и красиво, поэтому полезно настраивать внешний вид информации, которая будет напечатана. Это можно сделать реализовав типаж fmt::Display вручную, который использует маркер {} для печати. Его реализация выглядит следующим образом:
#![allow(unused)]
fn main() {
// Импортируем (с помощью `use`) модуль `fmt`, чтобы мы могли его использовать.
use std::fmt;
// Определяем структуру, для которой будет реализован `fmt::Display`.
// Это простая кортежная структура c именем `Structure`, которая хранит в себе `i32`.
struct Structure(i32);
// Чтобы была возможность использовать маркер `{}`
// `типаж (trait) fmt::Display` должен быть реализован вручную