Продвинутое форматирование чисел
Краткое описание
В этом уроке изучаем продвинутые возможности форматирования в пакете 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для правильной сортировки файлов в проводнике