Раздел 22 · Go

Ввод и форматирование: fmt, bufio, strconv

junior~60 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

Перед этим уроком

Ввод и форматирование: fmt, bufio, strconv

После трёх уроков теории ты дозрел до того, чтобы программа умела говорить с пользователем. Этот урок про две стороны одного предмета: как читать ввод и как красиво печатать вывод. Параллельно дам strconv, потому что без него не парсится ни одно число.

После урока пойдём в 05-debugging, потому что чтобы пользоваться отладчиком, надо уметь печатать промежуточные значения и понимать что показывает delve.

1. Печать в один глагол: Println

Самый простой способ что-то вывести:

import "fmt"

fmt.Println("hello")             // hello\n
fmt.Println("a =", a, "b =", b)  // через пробел, плюс \n в конце
fmt.Print("no newline")          // без \n
fmt.Println()                    // только \n

Println ставит пробелы между аргументами и \n в конце. Это неформатированный вывод, его хватает на 70% случаев.

Для форматированного вывода идём в Printf:

fmt.Printf("name=%s age=%d\n", "Vasya", 30)
// name=Vasya age=30

Главные три формы:

ФункцияКуда пишетЧто возвращает
Print, Println, Printfв os.Stdoutколичество байт и error
Sprint, Sprintln, Sprintfвозвращает строкуstring
Fprint, Fprintln, Fprintfв любой io.Writerколичество байт и error

Fprintf это самая универсальная форма: можно писать в файл, в HTTP-ответ, в os.Stderr, в strings.Builder. Println это сахар поверх Fprintln(os.Stdout, ...).

2. Verbs, часть 1: базовый минимум

Verb это %-метка, заменяемая на следующий аргумент. На джуновский набор хватает шести:

VerbЧто показываетПример
%vзначение в “разумной” дефолтной форме%v для Point{1,2} это {1 2}
%dцелое число в десятичной%d для 42 это 42
%sстрока как есть%s для "hi" это hi
%ttrue или false%t для true это true
%ffloat в фиксированной нотации%f для 3.14 это 3.140000
%cруна как символ%c для 1103 это я

Минимальный мастер-класс:

type Point struct{ X, Y int }
p := Point{1, 2}

fmt.Printf("%v\n", p)    // {1 2}
fmt.Printf("%d\n", 42)   // 42
fmt.Printf("%s\n", "hi") // hi
fmt.Printf("%t\n", 1<2)  // true
fmt.Printf("%f\n", 3.14) // 3.140000
fmt.Printf("%c\n", 'я')  // я

Ловушка с числами: %d на string это panic-в-рантайме (точнее, печатается %!d(string=hi)). Поэтому запоминай: тип аргумента и verb должны совпадать.

3. Verbs, часть 2: про структуру и ширину

Когда хочется что-то более выразительное:

VerbКогда нуженПример
%+vзначение с именами полей структуры%+v для Point{1,2} это {X:1 Y:2}
%#vGo-синтаксис, как литерал%#v для Point{1,2} это main.Point{X:1, Y:2}
%Tтип значения%T для 1.5 это float64
%qстрока в кавычках, экранированная%q для hi"a это "hi\"a"
%pуказатель в hex%p для &x это 0xc0000180a0
%x, %Xhex, нижний или верхний регистр%x для 255 это ff, %X это FF
%oв восьмеричной%o для 8 это 10
%bв двоичной%b для 5 это 101
%e, %Efloat в экспоненциальной%e для 1234.5 это 1.234500e+03
%g, %Gfloat “красивое” (без хвостовых нулей)%g для 3.14 это 3.14
%UUnicode code point%U для ‘я’ это U+044F

И флаги ширины и точности перед verb:

fmt.Printf("%5d|", 42)      // "   42|"   ширина 5, выравнивание справа
fmt.Printf("%-5d|", 42)     // "42   |"   ширина 5, выравнивание слева
fmt.Printf("%05d|", 42)     // "00042|"   ширина 5, паддинг нулями
fmt.Printf("%.2f|", 3.14159)// "3.14|"    точность 2 знака
fmt.Printf("%8.2f|", 3.14)  // "    3.14|" ширина 8 точность 2
fmt.Printf("%-15s|", "go")  // "go             |" строка ширины 15 слева

Это полностью совпадает с printf из C. Шпаргалка для печати таблицы:

type Row struct {
    Name   string
    Age    int
    Rating float64
}

rows := []Row{
    {"Vasya", 30, 9.45},
    {"Lena",  28, 8.7},
    {"Bob",   45, 9.0},
}

for _, r := range rows {
    fmt.Printf("%-15s %3d %8.2f\n", r.Name, r.Age, r.Rating)
}

// Vasya            30     9.45
// Lena             28     8.70
// Bob              45     9.00

Когда что использовать на практике

СитуацияVerb
Логи “переменная X = …”%v
Дебаг структуры с именами полей%+v
“Хочу видеть точно как Go это написал бы”%#v
“Хочу узнать тип переменной”%T
Печать строки в логах (видеть кавычки и эскейпы)%q
Адрес указателя%p
Hex-дамп байт%x, или %02x (с паддингом нулями)

%v это твой default, %+v для дебага структур, %T чтобы быстро проверить, что у тебя за тип. Этих трёх хватит на 80% форматирования.

премиум-урок

Продолжение в премиуме: 1 200 ₽ в месяц или 10 000 ₽ в год. Вместе с ним серверные проверки задач и школьные токены AI-коуча.

Оплата пока не подключена: премиум и курсы открываются промокодом.