Продвинутое форматирование чисел

Краткое описание

В этом уроке изучаем продвинутые возможности форматирования в пакете fmt: контроль ширины полей, выравнивание, заполнение нулями, управление точностью float и работу со знаками. Эти навыки полезны для создания таблиц, отчётов и форматирования имён файлов, хотя в повседневной разработке используются нечасто.

Ключевые концепции

Ширина поля: %5d

Резервирование места под вывод числа:

fmt.Printf("|%d|\n", 12)      // |12|
fmt.Printf("|%5d|\n", 12)     // |   12| (правое выравнивание)
fmt.Printf("|%5d|\n", 123)    // |  123|
fmt.Printf("|%5d|\n", 12345)  // |12345|
fmt.Printf("|%5d|\n", 123456) // |123456| (ширина не ограничивает)

Принцип: %5d резервирует 5 символов, число прижимается вправо, слева добавляются пробелы.

Левое выравнивание: %-5d

Флаг минус (-) прижимает число к левому краю:

fmt.Printf("|%-5d|\n", 12)    // |12   |
fmt.Printf("|%-5d|\n", 123)   // |123  |
fmt.Printf("|%-5d|\n", 12345) // |12345|

Применение: создание читаемых таблиц в консоли.

Практика: создание таблицы

fmt.Printf("%-10s %5s %8s\n", "Товар", "Кол-во", "Цена")
fmt.Printf("%-10s %5d %8.2f\n", "Яблоки", 10, 150.50)
fmt.Printf("%-10s %5d %8.2f\n", "Бананы", 5, 89.99)
fmt.Printf("%-10s %5d %8.2f\n", "Апельсины", 20, 120.00)

// Вывод:
// Товар      Кол-во     Цена
// Яблоки         10   150.50
// Бананы          5    89.99
// Апельсины      20   120.00

Заполнение нулями: %05d

Нули вместо пробелов — для ID, нумерации файлов, форматирования времени:

fmt.Printf("%03d\n", 7)    // 007
fmt.Printf("%05d\n", 42)   // 00042
fmt.Printf("%06d\n", 123)  // 000123

// Отрицательные числа - знак минус занимает место
fmt.Printf("%05d\n", -42)  // -0042 (минус + 4 символа)
fmt.Printf("%04d\n", -7)   // -007

Важно: знак минуса занимает один символ из зарезервированной ширины.

Практическое применение заполнения нулями

Имена файлов (правильная сортировка)

fileNumber := 5
fmt.Printf("document_%03d.txt\n", fileNumber)
// document_005.txt

// Почему не document_5.txt?
// Сортировка: file_1.txt, file_10.txt, file_2.txt ❌ (неправильно)
// С нулями:   file_01.txt, file_02.txt, file_10.txt ✅ (правильно)

Форматирование времени

hours := 19
minutes := 5
seconds := 3

fmt.Printf("%02d:%02d:%02d\n", hours, minutes, seconds)
// 19:05:03

ID транзакций

transactionID := 1234
fmt.Printf("TRX-%08d\n", transactionID)
// TRX-00001234

Точность float: %.2f

По умолчанию %f выводит 6 знаков, можно управлять:

pi := 3.14159265359

fmt.Printf("%f\n", pi)     // 3.141593 (6 знаков по умолчанию)
fmt.Printf("%.2f\n", pi)   // 3.14
fmt.Printf("%.4f\n", pi)   // 3.1416 (округление!)
fmt.Printf("%.0f\n", pi)   // 3

Внимание: применяется математическое округление:

value := 3.14567

fmt.Printf("%.3f\n", value)  // 3.146 (7→6, округлено до 5)
fmt.Printf("%.2f\n", value)  // 3.15 (5→округляем вверх)

Ширина + точность: %8.2f

Формат: %[ширина].[точность]f — комбинация резервирования места и точности:

price := 123.45

fmt.Printf("|%8.2f|\n", price)
// |  123.45|
//  ^^^^^^^^ = 8 символов всего
//  123.45 = 6 символов (1+2+3+точка+4+5)
//  Остаток: 2 пробела слева

Разбор компонентов:

  • 8 — общая ширина поля (включая точку и дробную часть)
  • .2 — два знака после запятой
price1 := 12.5
price2 := 123.456
price3 := 1234.56

fmt.Printf("|%8.2f|\n", price1)  // |   12.50|
fmt.Printf("|%8.2f|\n", price2)  // |  123.46| (округлено)
fmt.Printf("|%8.2f|\n", price3)  // | 1234.56|

// С левым выравниванием
fmt.Printf("|%-8.2f|\n", price1) // |12.50   |

Явный знак +: %+d

По умолчанию плюс опускается, но можно показать явно:

positive := 42
negative := -42

// Без флага +
fmt.Printf("%d\n", positive)  // 42
fmt.Printf("%d\n", negative)  // -42

// С флагом +
fmt.Printf("%+d\n", positive) // +42
fmt.Printf("%+d\n", negative) // -42

Применение:

// Температура
fmt.Printf("Температура: %+d°C\n", 25)   // +25°C
fmt.Printf("Температура: %+d°C\n", -5)   // -5°C

// Изменение цены акций
fmt.Printf("Изменение: %+.2f%%\n", 5.3)   // +5.30%
fmt.Printf("Изменение: %+.2f%%\n", -2.1)  // -2.10%

// Баланс счёта
fmt.Printf("Баланс: %+.2f руб.\n", 1000.50) // +1000.50 руб.

Пробел для знака: % d

Резервирует место под знак, но для положительных ставит пробел (не плюс):

positive := 42
negative := -42

fmt.Printf("|% d|\n", positive)  // | 42| (пробел вместо +)
fmt.Printf("|% d|\n", negative)  // |-42| (минус)

Сравнение трёх вариантов:

fmt.Printf("|%d| и |%d|\n", 42, -42)      // |42| и |-42|
fmt.Printf("|%+d| и |%+d|\n", 42, -42)    // |+42| и |-42|
fmt.Printf("|% d| и |% d|\n", 42, -42)    // | 42| и |-42|

Применение: выравнивание чисел в столбце:

fmt.Printf("Дельта: % 5d руб.\n", 150)  // Дельта:   150 руб.
fmt.Printf("Дельта: % 5d руб.\n", -75)  // Дельта:   -75 руб.
fmt.Printf("Дельта: % 5d руб.\n", 0)    // Дельта:     0 руб.

Практические примеры

Финансовый отчёт

fmt.Printf("%-20s %12s %12s\n", "Категория", "Доход", "Расход")
fmt.Println("---------------------------------------------")

fmt.Printf("%-20s %+12.2f %+12.2f\n", "Продажи", 15000.50, -8500.25)
fmt.Printf("%-20s %+12.2f %+12.2f\n", "Услуги", 7500.00, -3200.00)
fmt.Printf("%-20s %+12.2f %+12.2f\n", "Прочее", 1250.75, -450.50)

fmt.Println("---------------------------------------------")
total := 11600.50
fmt.Printf("%-20s %+12.2f\n", "Итого:", total)

// Вывод:
// Категория            Доход      Расход
// ---------------------------------------------
// Продажи           +15000.50    -8500.25
// Услуги             +7500.00    -3200.00
// Прочее             +1250.75     -450.50
// ---------------------------------------------
// Итого:            +11600.50

Таблица с выравниванием

fmt.Printf("%-15s %10s %10s\n", "Название", "Количество", "Цена")
fmt.Printf("%-15s %10d %10.2f\n", "Товар А", 100, 1250.50)
fmt.Printf("%-15s %10d %10.2f\n", "Товар Б", 50, 750.00)
fmt.Printf("%-15s %10d %10.2f\n", "Товар В", 200, 2500.99)

// Название        Количество       Цена
// Товар А                100    1250.50
// Товар Б                 50     750.00
// Товар В                200    2500.99

Универсальная формула форматирования

%[флаги][ширина][.точность]тип

Флаги:
  -     левое выравнивание
  +     показывать знак для положительных
  0     заполнять нулями
  пробел  резервировать место под знак

Примеры:
%-10s    строка, левое выравнивание, 10 символов
%+5d     число со знаком, правое выравнивание, 5 символов
%05d     число с нулями, 5 символов
%8.2f    float, 8 символов общей ширины, 2 знака после запятой
%+8.2f   float со знаком, 8 символов, 2 знака

Важные моменты

1. Ширина не ограничивает, а резервирует

Если число не помещается в указанную ширину, оно выведется полностью:

fmt.Printf("%3d\n", 12345)  // 12345 (не обрезается)

2. Знак минуса занимает символ

fmt.Printf("%05d\n", -42)  // -0042 (минус + 4 цифры = 5 символов)

3. Округление применяется автоматически

fmt.Printf("%.2f\n", 3.146)  // 3.15 (округлено вверх)

4. Работает для строк тоже

fmt.Printf("|%8s|\n", "Go")   // |      Go|
fmt.Printf("|%-8s|\n", "Go")  // |Go      |

5. Нишевая функциональность

Автор подчёркивает: в реальной разработке это используется редко. Основные случаи:

  • Консольные таблицы и отчёты
  • Форматирование логов (но обычно уже настроено)
  • Генерация имён файлов с нумерацией
  • Специфические требования к выводу

6. Сортировка файлов

Без нулей: file_1.txt, file_10.txt, file_2.txt
С нулями: file_01.txt, file_02.txt, file_10.txt

7. Комбинируйте флаги

fmt.Printf("%+8.2f\n", 123.4)   // + 123.40 (знак + ширина + точность)
fmt.Printf("%-+8.2f\n", 123.4)  // +123.40  (левое выравнивание + знак)

Best Practices

1. Используйте для табличного вывода

// Хорошо - читаемая таблица
fmt.Printf("%-10s %5d %8.2f\n", name, qty, price)

// Плохо - непонятный вывод
fmt.Println(name, qty, price)

2. Заполняйте нулями номера файлов

// Хорошо - правильная сортировка
fileName := fmt.Sprintf("file_%03d.txt", i)

// Плохо - неправильная сортировка в проводнике
fileName := fmt.Sprintf("file_%d.txt", i)

3. Явный знак для финансовых данных

// Хорошо - видны прибыль и убыток
fmt.Printf("Изменение: %+.2f%%\n", change)

// Хуже - непонятно для положительных
fmt.Printf("Изменение: %.2f%%\n", change)

4. Не переусердствуйте

Автор предупреждает: не тратьте много времени на изучение всех тонкостей. Знайте о существовании, но используйте по необходимости.

Что запомнить

  • %5d — ширина поля (5 символов, правое выравнивание)
  • %-5d — левое выравнивание (флаг -)
  • %05d — заполнение нулями
  • %.2f — два знака после запятой (округление)
  • %8.2f — ширина 8 + точность 2
  • %+d — явный знак + для положительных чисел
  • % d — пробел вместо + (для выравнивания)
  • Знак минуса занимает символ из ширины
  • Ширина не ограничивает, а резервирует место
  • Работает с int, float и string
  • Нишевая функциональность — не критична для большинства задач
  • Основное применение: таблицы, отчёты, нумерация файлов
  • Используйте %03d для правильной сортировки файлов в проводнике

Полезные ссылки