Форматированный вывод

Вывод обрабатывается несколькими макросами, которые определены в std::fmt. Вот некоторые из них:

  • format!: записывает форматированный текст в String.
  • print!: работает аналогично с format!, но текст выводится в консоль (io::stdout).
  • println!: аналогично print!, но в конце добавляется переход на новую строку.
  • eprint!: аналогично format!, но текст выводится в стандартный поток ошибок (io::stderr).
  • eprintln!: аналогично eprint!, но в конце добавляется переход на новую строку.

Весь текст обрабатывается аналогичным образом. Плюс данного метода в том, что корректность форматирования будет проверена на этапе компиляции программы.

fn main() {
    // `{}` автоматически будет заменено на
    // аргументы. Они будут преобразованы в строку.
    println!("{} дней", 31);

    // Без суффиксов, 31 является i32. Можно изменить тип 31,
    // используя суффикс.

    // Существует множество способов работы с форматированным выводом. Можно указать
    // позицию для каждого аргумента.
    println!("{0}, это {1}. {1}, это {0}", "Алиса", "Боб");

    // Так же можно именовать аргументы.
    println!("{subject} {verb} {object}",
             object="ленивую собаку",
             subject="быстрая коричневая лиса",
             verb="прыгает через");

    println!("{} из {:b} людей знают, что такое двоичный код, а остальные нет.", 1, 2);

    // Можно выравнивать текст, сдвигая его на указанную ширину.
    // Данный макрос отобразит в консоли
    // "     1". 5 пробелов и "1".
    println!("{number:>width$}", number=1, width=6);

    // Можно добавить к цифрам пару нулей. Данный макрос выведет "000001".
    println!("{number:0>width$}", number=1, width=6);

    // Компилятор обязательно проверит, что в макрос передано правильное количество
    // аргументов.
    println!("Меня зовут {0}, {1} {0}", "Бонд");
    // ИСПРАВЬТЕ ^ Добавьте недостающий аргумент: "Джеймс"

    // Создаём структуру, которая хранит в себе `i32`. Назовём её `Structure`.
    #[allow(dead_code)]
    struct Structure(i32);

    // Однако, пользовательские типы данных, например, как эта структура
    // требуют более сложной обработки для вывода. Данный код не будет работать.
    println!("Эта структура `{}` не хочет выводится на экран...", Structure(3));
    // ИСПРАВЬТЕ ^ Закомментируйте эту строку.
}

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