Пакет fmt
Обзор
Пакет fmt реализует форматированный ввод-вывод с помощью функций, аналогичных printf и scanf в C. «Глаголы» формата заимствованы из C, но они проще.
Вывод
Существуют четыре семейства функций вывода, различающиеся местом назначения. Print, Println и Printf записывают в os.Stdout; Sprint, Sprintln и Sprintf возвращают строку; Fprint, Fprintln и Fprintf записывают в io.Writer; а Append, Appendln и Appendf добавляют вывод в срез байтов.
Форматирование функций внутри каждого семейства определяется окончанием их имени. Print, Sprint, Fprint и Append используют формат по умолчанию для каждого аргумента, добавляя пробел между операндами, если ни один из них не является строкой. Println, Sprintln, Fprintln и Appendln всегда добавляют пробелы и завершают вывод символом новой строки. Printf, Sprintf, Fprintf и Appendf используют последовательность «глаголов» для управления форматированием.
Глаголы:
Общие:
%v the value in a default format when printing structs, the plus flag (%+v) adds field names %#v a Go-syntax representation of the value (floating-point infinities and NaNs print as ±Inf and NaN) %T a Go-syntax representation of the type of the value %% a literal percent sign; consumes no value
Логические значения:
%t the word true or false
Целые числа:
%b base 2 %c the character represented by the corresponding Unicode code point %d base 10 %o base 8 %O base 8 with 0o prefix %q a single-quoted rune literal safely escaped with Go syntax. %x base 16, with lower-case letters for a-f %X base 16, with upper-case letters for A-F %U Unicode format: U+1234; same as "U+%04X"
Числа с плавающей точкой и компоненты комплексных чисел:
%b decimalless scientific notation with exponent a power of two, in the manner of strconv.FormatFloat with the 'b' format, e.g. -123456p-78 %e scientific notation, e.g. -1.234456e+78 %E scientific notation, e.g. -1.234456E+78 %f decimal point but no exponent, e.g. 123.456 %F synonym for %f %g %e for large exponents, %f otherwise. Precision is discussed below. %G %E for large exponents, %F otherwise %x hexadecimal notation (with decimal power of two exponent), e.g. -0x1.23abcp+20 %X upper-case hexadecimal notation, e.g. -0X1.23ABCP+20 The exponent is always a decimal integer. For formats other than %b the exponent is at least two digits.
Строка и срез байтов (для этих глаголов обрабатываются одинаково):
%s the uninterpreted bytes of the string or slice %q a double-quoted string safely escaped with Go syntax %x base 16, lower-case, two characters per byte %X base 16, upper-case, two characters per byte
Срез:
%p address of 0th element in base 16 notation, with leading 0x
Указатель:
%p base 16 notation, with leading 0x The %b, %d, %o, %x and %X verbs also work with pointers, formatting the value exactly as if it were an integer.
Формат по умолчанию для %v:
bool: %t int, int8 etc.: %d uint, uint8 etc.: %d, %#x if printed with %#v float32, complex64, etc: %g string: %s chan: %p pointer: %p
Для составных объектов элементы рекурсивно выводятся по следующим правилам и в таком виде:
struct: {field0 field1 ...}
array, slice: [elem0 elem1 ...]
maps: map[key1:value1 key2:value2 ...]
pointer to above: &{}, &[], &map[]
Ширина задается необязательным десятичным числом, непосредственно предшествующим глаголу. Если она не указана, используется ширина, необходимая для представления значения. Точность указывается после (необязательной) ширины: точка, за которой следует десятичное число. Если точка отсутствует, используется точность по умолчанию. Точка без следующего за ней числа задает точность, равную нулю. Примеры:
%f default width, default precision %9f width 9, default precision %.2f default width, precision 2 %9.2f width 9, precision 2 %9.f width 9, precision 0
Ширина и точность измеряются в единицах кодовых точек Юникода, то есть рун. (Это отличается от printf в C, где единицей измерения всегда являются байты.) Один или оба флага можно заменить символом '*', тогда их значения будут получены из следующего операнда (перед форматируемым), который должен иметь тип int.
Для большинства значений ширина — это минимальное количество рун для вывода; при необходимости форматированное представление дополняется пробелами.
Однако для строк, срезов байтов и массивов байтов точность ограничивает длину форматируемых входных данных (а не размер вывода), обрезая их при необходимости. Обычно длина измеряется в рунах, но для этих типов при форматировании с помощью %x или %X она измеряется в байтах.
Для чисел с плавающей точкой ширина задает минимальную ширину поля, а точность — количество знаков после десятичной точки, если это применимо; исключение составляют %g/%G, для которых точность задает максимальное количество значащих цифр (конечные нули удаляются). Например, для значения 12.345 формат %6.3f выводит 12.345, а %.3g — 12.3. Точность по умолчанию для %e, %f и %#g равна 6; для %g используется минимальное количество цифр, необходимое для однозначного определения значения.
Для комплексных чисел ширина и точность применяются независимо к каждой из двух компонент, а результат заключается в скобки, поэтому применение %f к 1.2+3.4i дает (1.200000+3.400000i).
При форматировании отдельной целочисленной кодовой точки или строки рун (типа []rune) с помощью %q недопустимые кодовые точки Юникода заменяются на символ замены Юникода U+FFFD, как в strconv.QuoteRune.
Другие флаги:
'+' always print a sign for numeric values; guarantee ASCII-only output for %q (%+q) '-' pad with spaces on the right rather than the left (left-justify the field) '#' alternate format: add leading 0b for binary (%#b), 0 for octal (%#o), 0x or 0X for hex (%#x or %#X); suppress 0x for %p (%#p); for %q, print a raw (backquoted) string if [strconv.CanBackquote] returns true; always print a decimal point for %e, %E, %f, %F, %g and %G; do not remove trailing zeros for %g and %G; write e.g. U+0078 'x' if the character is printable for %U (%#U) ' ' (space) leave a space for elided sign in numbers (% d); put spaces between bytes printing strings or slices in hex (% x, % X) '0' pad with leading zeros rather than spaces; for numbers, this moves the padding after the sign
Флаги игнорируются глаголами, которые их не поддерживают. Например, альтернативного десятичного формата нет, поэтому %#d и %d ведут себя одинаково.
Для каждой функции, подобной Printf, существует также функция Print, которая не принимает формат и эквивалентна применению %v к каждому операнду. Другой вариант, Println, вставляет пробелы между операндами и добавляет символ новой строки.
Независимо от глагола, если операнд является значением интерфейсного типа, используется его внутреннее конкретное значение, а не сам интерфейс. Таким образом:
var i interface{} = 23
fmt.Printf("%v\n", i)
выведет 23.
За исключением случаев вывода с помощью глаголов %T и %p, к операндам, реализующим определенные интерфейсы, применяются особые правила форматирования. Они применяются в следующем порядке:
1. Если операнд — это reflect.Value, он заменяется конкретным значением, которое содержит, после чего форматирование продолжается по следующему правилу.
2. Если операнд реализует интерфейс Formatter, вызывается соответствующий метод. В этом случае интерпретация глаголов и флагов определяется этой реализацией.
3. Если используется глагол %v с флагом # (%#v), а операнд реализует интерфейс GoStringer, вызывается соответствующий метод.
Если формат (неявно равный %v для Println и т. д.) допустим для строки (%s %q %x %X) или равен %v, но не %#v, применяются следующие два правила:
4. Если операнд реализует интерфейс error, для преобразования объекта в строку вызывается метод Error, после чего строка форматируется в соответствии с требованиями глагола (если он есть).
5. Если операнд реализует метод String() string, для преобразования объекта в строку вызывается этот метод, после чего строка форматируется в соответствии с требованиями глагола (если он есть).
Для составных операндов, таких как срезы и структуры, формат применяется рекурсивно к элементам каждого операнда, а не к операнду целиком. Таким образом, %q заключит в кавычки каждый элемент среза строк, а %6.2f будет управлять форматированием каждого элемента массива чисел с плавающей точкой.
Однако при выводе среза байтов с помощью строкового глагола (%s %q %x %X) он обрабатывается так же, как строка, то есть как единый элемент.
Чтобы избежать рекурсии в таких случаях, как
type X string
func (x X) String() string { return Sprintf("<%s>", x) }
преобразуйте значение перед повторным вызовом:
func (x X) String() string { return Sprintf("<%s>", string(x)) }
Бесконечную рекурсию также могут вызывать самоссылочные структуры данных, например срез, содержащий себя в качестве элемента, если у его типа есть метод String. Однако такие случаи редки, и пакет не защищает от них.
При выводе структуры fmt не может и потому не вызывает методы форматирования, такие как Error или String, для неэкспортируемых полей.
Явные индексы аргументов
В функциях Printf, Sprintf, Fprintf и Appendf по умолчанию каждый глагол форматирования обрабатывает следующий аргумент, переданный при вызове. Однако запись [n] непосредственно перед глаголом указывает, что вместо этого нужно форматировать аргумент с индексом n, начиная отсчет с единицы. Такая же запись перед '*' для ширины или точности выбирает индекс аргумента, содержащего соответствующее значение. После обработки выражения в квадратных скобках [n] последующие глаголы будут использовать аргументы n+1, n+2 и т. д., если не указано иное.
Например,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
выведет "22 11", тогда как
fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6)
эквивалентно
fmt.Sprintf("%6.2f", 12.0)
и выведет " 12.00". Поскольку явный индекс влияет на последующие глаголы, эту запись можно использовать для повторного вывода одних и тех же значений, сбросив индекс на первый аргумент, который нужно повторить:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
выведет "16 17 0x10 0x11".
Ошибки форматирования
Если для глагола передан недопустимый аргумент, например строка для %d, сгенерированная строка будет содержать описание проблемы, как в этих примерах:
Wrong type or unknown verb: %!verb(type=value)
Printf("%d", "hi"): %!d(string=hi)
Too many arguments: %!(EXTRA type=value)
Printf("hi", "guys"): hi%!(EXTRA string=guys)
Too few arguments: %!verb(MISSING)
Printf("hi%d"): hi%!d(MISSING)
Non-int for width or precision: %!(BADWIDTH) or %!(BADPREC)
Printf("%*s", 4.5, "hi"): %!(BADWIDTH)hi
Printf("%.*s", 4.5, "hi"): %!(BADPREC)hi
Invalid or invalid use of argument index: %!(BADINDEX)
Printf("%*[2]d", 7): %!d(BADINDEX)
Printf("%.[2]d", 7): %!d(BADINDEX)
Все ошибки начинаются со строки "%!", за которой иногда следует один символ (глагол), и заканчиваются описанием в скобках.
Если вызов метода Error или String из процедуры печати приводит к панике, пакет fmt переформатирует сообщение об ошибке, полученное при панике, добавляя указание на то, что она возникла в пакете fmt. Например, если метод String вызывает panic("bad"), итоговое отформатированное сообщение будет выглядеть так:
%!s(PANIC=bad)
%!s показывает только глагол печати, использовавшийся в момент возникновения сбоя. Однако если паника вызвана nil-получателем метода Error, String или GoString, выводом будет строка без дополнительных пометок "<nil>".
Многие пакеты, чьи API связаны с форматированием строк, предоставляют набор из трёх функций, подобных Print, Printf и Println. Например, функции log.Print, log.Printf и log.Println передают свои аргументы соответствующим функциям этого пакета. Чтобы избежать путаницы, другим функциям-обёрткам следует придерживаться принятых в этом пакете соглашений об именовании и поведении. В частности, одной функции не следует выбирать между буквальным выводом (как у Print) и форматированным выводом (как у Printf) в зависимости от числа аргументов; вместо этого следует предоставить отдельные функции.
Сканирование
Аналогичный набор функций сканирует форматированный текст и извлекает из него значения. Scan, Scanf и Scanln читают данные из os.Stdin; Fscan, Fscanf и Fscanln читают данные из указанного io.Reader; Sscan, Sscanf и Sscanln читают данные из строки-аргумента.
Scan, Fscan и Sscan рассматривают символы новой строки во входных данных как пробелы.
Scanln, Fscanln и Sscanln прекращают сканирование на символе новой строки и требуют, чтобы за элементами следовал символ новой строки или EOF.
Scanf, Fscanf и Sscanf разбирают аргументы согласно строке формата, аналогично Printf. В дальнейшей части текста под «пробелом» подразумевается любой символ пробельного символа Unicode, кроме символа новой строки.
В строке формата глагол, которому предшествует символ %, считывает и разбирает входные данные; подробнее эти глаголы описаны ниже. Символ в формате, отличный от %, пробела или символа новой строки, считывает ровно этот символ из входных данных, где он должен присутствовать. Символ новой строки, которому в строке формата предшествует ноль или более пробелов, считывает ноль или более пробелов во входных данных, за которыми следует один символ новой строки или конец входных данных. Пробел после символа новой строки в строке формата считывает ноль или более пробелов во входных данных. В остальных случаях любая последовательность из одного или более пробелов в строке формата считывает как можно больше пробелов во входных данных. Если последовательность пробелов в строке формата не стоит рядом с символом новой строки, она должна считать хотя бы один пробел из входных данных или дойти до их конца.
Обработка пробелов и символов новой строки отличается от обработки в семействе функций scanf языка C: в C символы новой строки рассматриваются как любые другие пробелы, и отсутствие пробелов во входных данных при обработке последовательности пробелов в строке формата никогда не считается ошибкой.
Глаголы работают аналогично глаголам Printf. Например, %x сканирует целое число как шестнадцатеричное, а %v сканирует значение в формате представления по умолчанию. Глаголы Printf %p и %T, а также флаги # и + не реализованы. Для значений с плавающей точкой и комплексных значений все допустимые глаголы форматирования (%b %e %E %f %F %g %G %x %X и %v) эквивалентны и принимают как десятичную, так и шестнадцатеричную запись (например: "2.3e+7", "0x4.5p-8"), а также подчёркивания-разделители цифр (например: "3.14159_26535_89793").
Входные данные, обрабатываемые глаголами, неявно разделяются пробелами: реализация каждого глагола, кроме %c, начинает с удаления начальных пробелов из оставшихся входных данных, а глагол %s (и %v при чтении в строку) прекращает считывание на первом пробеле или символе новой строки.
При сканировании целых чисел без формата или с глаголом %v допускаются знакомые префиксы для указания системы счисления: 0b (двоичная), 0o и 0 (восьмеричная), а также 0x (шестнадцатеричная); также допускаются подчёркивания-разделители цифр.
Ширина интерпретируется во входном тексте, но синтаксиса для сканирования с точностью нет (не %5.2f, а только %5f). Если указана ширина, она применяется после удаления начальных пробелов и задаёт максимальное число рун, считываемых для обработки глагола. Например,
Sscanf(" 1234567 ", "%5s%d", &s, &i)
задаст для s значение "12345", а для i — 67, тогда как
Sscanf(" 12 34 567 ", "%5s%d", &s, &i)
задаст для s значение "12", а для i — 34.
Во всех функциях сканирования символ возврата каретки, за которым непосредственно следует символ новой строки, рассматривается как обычный символ новой строки (\r\n означает то же, что и \n).
Во всех функциях сканирования, если операнд реализует метод Scan (то есть реализует интерфейс Scanner), этот метод будет использоваться для сканирования текста соответствующего операнда. Кроме того, если число отсканированных аргументов меньше числа переданных аргументов, возвращается ошибка.
Все сканируемые аргументы должны быть либо указателями на базовые типы, либо реализациями интерфейса Scanner.
Как и Scanf и Fscanf, Sscanf не обязана считывать все входные данные. Нет способа узнать, какую часть входной строки использовала Sscanf.
Примечание: Fscan и другие функции могут прочитать один символ (руну) сверх объёма входных данных, который они возвращают, а это означает, что цикл с вызовом функции сканирования может пропустить часть входных данных. Обычно это проблема только в том случае, если между входными значениями нет пробелов. Если переданный в Fscan считыватель реализует ReadRune, для чтения символов будет использоваться этот метод. Если считыватель также реализует UnreadRune, этот метод будет использоваться для сохранения символа, и последующие вызовы не будут терять данные. Чтобы добавить методы ReadRune и UnreadRune считывателю, у которого их нет, используйте bufio.NewReader.
Пример (форматы)
Эти примеры демонстрируют основы печати с использованием строки формата. Printf, Sprintf и Fprintf принимают строку формата, которая задаёт форматирование последующих аргументов. Например, %d (мы называем его «глаголом») означает, что соответствующий аргумент, который должен быть целым числом (или чем-либо, содержащим целые числа, например срезом целых чисел), нужно вывести в десятичной системе счисления. Глагол %v («v» от «value», значение) всегда форматирует аргумент в формате по умолчанию — так же, как его вывели бы Print или Println. Специальный глагол %T («T» от «Type», тип) выводит тип аргумента, а не его значение. Примеры не охватывают все случаи; полное описание см. в комментарии к пакету.
Код:
// A basic set of examples showing that %v is the default format, in this
// case decimal for integers, which can be explicitly requested with %d;
// the output is just what Println generates.
integer := 23
// Each of these prints "23" (without the quotes).
fmt.Println(integer)
fmt.Printf("%v\n", integer)
fmt.Printf("%d\n", integer)
// The special verb %T shows the type of an item rather than its value.
fmt.Printf("%T %T\n", integer, &integer)
// Result: int *int
// Println(x) is the same as Printf("%v\n", x) so we will use only Printf
// in the following examples. Each one demonstrates how to format values of
// a particular type, such as integers or strings. We start each format
// string with %v to show the default output and follow that with one or
// more custom formats.
// Booleans print as "true" or "false" with %v or %t.
truth := true
fmt.Printf("%v %t\n", truth, truth)
// Result: true true
// Integers print as decimals with %v and %d,
// or in hex with %x, octal with %o, or binary with %b.
answer := 42
fmt.Printf("%v %d %x %o %b\n", answer, answer, answer, answer, answer)
// Result: 42 42 2a 52 101010
// Floats have multiple formats: %v and %g print a compact representation,
// while %f prints a decimal point and %e uses exponential notation. The
// format %6.2f used here shows how to set the width and precision to
// control the appearance of a floating-point value. In this instance, 6 is
// the total width of the printed text for the value (note the extra spaces
// in the output) and 2 is the number of decimal places to show.
pi := math.Pi
fmt.Printf("%v %g %.2f (%6.2f) %e\n", pi, pi, pi, pi, pi)
// Result: 3.141592653589793 3.141592653589793 3.14 ( 3.14) 3.141593e+00
// Complex numbers format as parenthesized pairs of floats, with an 'i'
// after the imaginary part.
point := 110.7 + 22.5i
fmt.Printf("%v %g %.2f %.2e\n", point, point, point, point)
// Result: (110.7+22.5i) (110.7+22.5i) (110.70+22.50i) (1.11e+02+2.25e+01i)
// Runes are integers but when printed with %c show the character with that
// Unicode value. The %q verb shows them as quoted characters, %U as a
// hex Unicode code point, and %#U as both a code point and a quoted
// printable form if the rune is printable.
smile := '😀'
fmt.Printf("%v %d %c %q %U %#U\n", smile, smile, smile, smile, smile, smile)
// Result: 128512 128512 😀 '😀' U+1F600 U+1F600 '😀'
// Strings are formatted with %v and %s as-is, with %q as quoted strings,
// and %#q as backquoted strings.
placeholders := `foo "bar"`
fmt.Printf("%v %s %q %#q\n", placeholders, placeholders, placeholders, placeholders)
// Result: foo "bar" foo "bar" "foo \"bar\"" `foo "bar"`
// Maps formatted with %v show keys and values in their default formats.
// The %#v form (the # is called a "flag" in this context) shows the map in
// the Go source format. Maps are printed in a consistent order, sorted
// by the values of the keys.
isLegume := map[string]bool{
"peanut": true,
"dachshund": false,
}
fmt.Printf("%v %#v\n", isLegume, isLegume)
// Result: map[dachshund:false peanut:true] map[string]bool{"dachshund":false, "peanut":true}
// Structs formatted with %v show field values in their default formats.
// The %+v form shows the fields by name, while %#v formats the struct in
// Go source format.
person := struct {
Name string
Age int
}{"Kim", 22}
fmt.Printf("%v %+v %#v\n", person, person, person)
// Result: {Kim 22} {Name:Kim Age:22} struct { Name string; Age int }{Name:"Kim", Age:22}
// The default format for a pointer shows the underlying value preceded by
// an ampersand. The %p verb prints the pointer value in hex. We use a
// typed nil for the argument to %p here because the value of any non-nil
// pointer would change from run to run; run the commented-out Printf
// call yourself to see.
pointer := &person
fmt.Printf("%v %p\n", pointer, (*int)(nil))
// Result: &{Kim 22} 0x0
// fmt.Printf("%v %p\n", pointer, pointer)
// Result: &{Kim 22} 0x010203 // See comment above.
// Arrays and slices are formatted by applying the format to each element.
greats := [5]string{"Kitano", "Kobayashi", "Kurosawa", "Miyazaki", "Ozu"}
fmt.Printf("%v %q\n", greats, greats)
// Result: [Kitano Kobayashi Kurosawa Miyazaki Ozu] ["Kitano" "Kobayashi" "Kurosawa" "Miyazaki" "Ozu"]
kGreats := greats[:3]
fmt.Printf("%v %q %#v\n", kGreats, kGreats, kGreats)
// Result: [Kitano Kobayashi Kurosawa] ["Kitano" "Kobayashi" "Kurosawa"] []string{"Kitano", "Kobayashi", "Kurosawa"}
// Byte slices are special. Integer verbs like %d print the elements in
// that format. The %s and %q forms treat the slice like a string. The %x
// verb has a special form with the space flag that puts a space between
// the bytes.
cmd := []byte("a⌘")
fmt.Printf("%v %d %s %q %x % x\n", cmd, cmd, cmd, cmd, cmd, cmd)
// Result: [97 226 140 152] [97 226 140 152] a⌘ "a⌘" 61e28c98 61 e2 8c 98
// Types that implement Stringer are printed the same as strings. Because
// Stringers return a string, we can print them using a string-specific
// verb such as %q.
now := time.Unix(123456789, 0).UTC() // time.Time implements fmt.Stringer.
fmt.Printf("%v %q\n", now, now)
// Result: 1973-11-29 21:33:09 +0000 UTC "1973-11-29 21:33:09 +0000 UTC"
Вывод:
23
23
23
int *int
true true
42 42 2a 52 101010
3.141592653589793 3.141592653589793 3.14 ( 3.14) 3.141593e+00
(110.7+22.5i) (110.7+22.5i) (110.70+22.50i) (1.11e+02+2.25e+01i)
128512 128512 😀 '😀' U+1F600 U+1F600 '😀'
foo "bar" foo "bar" "foo \"bar\"" `foo "bar"`
map[dachshund:false peanut:true] map[string]bool{"dachshund":false, "peanut":true}
{Kim 22} {Name:Kim Age:22} struct { Name string; Age int }{Name:"Kim", Age:22}
&{Kim 22} 0x0
[Kitano Kobayashi Kurosawa Miyazaki Ozu] ["Kitano" "Kobayashi" "Kurosawa" "Miyazaki" "Ozu"]
[Kitano Kobayashi Kurosawa] ["Kitano" "Kobayashi" "Kurosawa"] []string{"Kitano", "Kobayashi", "Kurosawa"}
[97 226 140 152] [97 226 140 152] a⌘ "a⌘" 61e28c98 61 e2 8c 98
1973-11-29 21:33:09 +0000 UTC "1973-11-29 21:33:09 +0000 UTC"
Пример (функции печати)
Print, Println и Printf по-разному располагают аргументы. В этом примере можно сравнить их поведение. Println всегда добавляет пробелы между выводимыми элементами, тогда как Print добавляет пробелы только между аргументами, не являющимися строками, а Printf делает именно то, что ему указано. Sprint, Sprintln, Sprintf, Fprint, Fprintln и Fprintf ведут себя так же, как соответствующие функции Print, Println и Printf, показанные здесь.
Код:
a, b := 3.0, 4.0
h := math.Hypot(a, b)
// Print inserts blanks between arguments when neither is a string.
// It does not add a newline to the output, so we add one explicitly.
fmt.Print("The vector (", a, b, ") has length ", h, ".\n")
// Println always inserts spaces between its arguments,
// so it cannot be used to produce the same output as Print in this case;
// its output has extra spaces.
// Also, Println always adds a newline to the output.
fmt.Println("The vector (", a, b, ") has length", h, ".")
// Printf provides complete control but is more complex to use.
// It does not add a newline to the output, so we add one explicitly
// at the end of the format specifier string.
fmt.Printf("The vector (%g %g) has length %g.\n", a, b, h)
Вывод:
The vector (3 4) has length 5. The vector ( 3 4 ) has length 5 . The vector (3 4) has length 5.
Указатель
Примеры
Файлы пакета
doc.go errors.go format.go print.go scan.go
func Append 1.19
func Append(b []byte, a ...any) []byte
Append форматирует аргументы, используя для них форматы по умолчанию, добавляет результат в срез байтов и возвращает обновлённый срез. Между аргументами добавляются пробелы, если ни один из них не является строкой.
func Appendf 1.19
func Appendf(b []byte, format string, a ...any) []byte
Appendf форматирует аргументы согласно спецификатору формата, добавляет результат в срез байтов и возвращает обновлённый срез.
func Appendln 1.19
func Appendln(b []byte, a ...any) []byte
Appendln форматирует аргументы, используя для них форматы по умолчанию, добавляет результат в срез байтов и возвращает обновлённый срез. Между аргументами всегда добавляются пробелы, а в конце добавляется символ новой строки.
func Errorf
func Errorf(format string, a ...any) (err error)
Errorf форматирует аргументы согласно спецификатору формата и возвращает строку в виде значения, удовлетворяющего интерфейсу error.
Если спецификатор формата содержит директиву %w с аргументом типа error, возвращённая ошибка будет реализовывать метод Unwrap, возвращающий этот аргумент. Если директив %w несколько, возвращённая ошибка будет реализовывать метод Unwrap, возвращающий []error со всеми аргументами %w в порядке их следования. Использовать директиву %w с аргументом, не реализующим интерфейс error, нельзя. В остальных случаях директива %w является синонимом %v.
Пример
Функция Errorf позволяет использовать возможности форматирования для создания информативных сообщений об ошибках.
Код:
const name, id = "bueller", 17
err := fmt.Errorf("user %q (id %d) not found", name, id)
fmt.Println(err.Error())
Вывод:
user "bueller" (id 17) not found
func FormatString 1.20
func FormatString(state State, verb rune) string
FormatString возвращает строку, представляющую полностью квалифицированную директиву форматирования, сохранённую в State, за которой следует глагол аргумента. (State сам по себе не содержит глагол.) Результат начинается со знака процента, за которым следуют флаги, ширина и точность. Отсутствующие флаги, ширина и точность опускаются. Эта функция позволяет Formatter восстановить исходную директиву, вызвавшую вызов Format.
func Fprint
func Fprint(w io.Writer, a ...any) (n int, err error)
Fprint форматирует аргументы, используя для них форматы по умолчанию, и записывает результат в w. Между аргументами добавляются пробелы, если ни один из них не является строкой. Функция возвращает количество записанных байтов и возникшую ошибку записи, если она есть.
Пример
Код:
const name, age = "Kim", 22
n, err := fmt.Fprint(os.Stdout, name, " is ", age, " years old.\n")
// The n and err return values from Fprint are
// those returned by the underlying io.Writer.
if err != nil {
fmt.Fprintf(os.Stderr, "Fprint: %v\n", err)
}
fmt.Print(n, " bytes written.\n")
Вывод:
Kim is 22 years old. 21 bytes written.
func Fprintf
func Fprintf(w io.Writer, format string, a ...any) (n int, err error)
Fprintf форматирует аргументы согласно спецификатору формата и записывает результат в w. Функция возвращает количество записанных байтов и возникшую ошибку записи, если она есть.
Пример
Код:
const name, age = "Kim", 22
n, err := fmt.Fprintf(os.Stdout, "%s is %d years old.\n", name, age)
// The n and err return values from Fprintf are
// those returned by the underlying io.Writer.
if err != nil {
fmt.Fprintf(os.Stderr, "Fprintf: %v\n", err)
}
fmt.Printf("%d bytes written.\n", n)
Вывод:
Kim is 22 years old. 21 bytes written.
func Fprintln
func Fprintln(w io.Writer, a ...any) (n int, err error)
Fprintln форматирует аргументы, используя для них форматы по умолчанию, и записывает результат в w. Между аргументами всегда добавляются пробелы, а в конце добавляется символ новой строки. Функция возвращает количество записанных байтов и возникшую ошибку записи, если она есть.
Пример
Код:
const name, age = "Kim", 22
n, err := fmt.Fprintln(os.Stdout, name, "is", age, "years old.")
// The n and err return values from Fprintln are
// those returned by the underlying io.Writer.
if err != nil {
fmt.Fprintf(os.Stderr, "Fprintln: %v\n", err)
}
fmt.Println(n, "bytes written.")
Вывод:
Kim is 22 years old. 21 bytes written.
func Fscan
func Fscan(r io.Reader, a ...any) (n int, err error)
Fscan сканирует текст, считанный из r, и сохраняет последовательные значения, разделённые пробелами, в последовательных аргументах. Переводы строк считаются пробелами. Функция возвращает количество успешно отсканированных элементов. Если оно меньше количества аргументов, err сообщит причину.
func Fscanf
func Fscanf(r io.Reader, format string, a ...any) (n int, err error)
Fscanf сканирует текст, считанный из r, и сохраняет последовательные значения, разделённые пробелами, в последовательных аргументах в соответствии с форматом. Функция возвращает количество успешно разобранных элементов. Переводы строк во входных данных должны соответствовать переводам строк в формате.
Пример
Код:
var (
i int
b bool
s string
)
r := strings.NewReader("5 true gophers")
n, err := fmt.Fscanf(r, "%d %t %s", &i, &b, &s)
if err != nil {
fmt.Fprintf(os.Stderr, "Fscanf: %v\n", err)
}
fmt.Println(i, b, s)
fmt.Println(n)
Вывод:
5 true gophers 3
func Fscanln
func Fscanln(r io.Reader, a ...any) (n int, err error)
Fscanln похожа на Fscan, но прекращает сканирование при переводе строки; после последнего элемента должен следовать перевод строки или EOF.
Пример
Код:
s := `dmr 1771 1.61803398875
ken 271828 3.14159`
r := strings.NewReader(s)
var a string
var b int
var c float64
for {
n, err := fmt.Fscanln(r, &a, &b, &c)
if err == io.EOF {
break
}
if err != nil {
panic(err)
}
fmt.Printf("%d: %s, %d, %f\n", n, a, b, c)
}
Вывод:
3: dmr, 1771, 1.618034 3: ken, 271828, 3.141590
func Print
func Print(a ...any) (n int, err error)
Print форматирует операнды с помощью форматов по умолчанию и записывает результат в стандартный вывод. Между операндами добавляются пробелы, если ни один из них не является строкой. Функция возвращает количество записанных байтов и любую возникшую ошибку записи.
Пример
Код:
const name, age = "Kim", 22 fmt.Print(name, " is ", age, " years old.\n") // It is conventional not to worry about any // error returned by Print.
Вывод:
Kim is 22 years old.
func Printf
func Printf(format string, a ...any) (n int, err error)
Printf форматирует данные согласно спецификатору формата и записывает результат в стандартный вывод. Функция возвращает количество записанных байтов и любую возникшую ошибку записи.
Пример
Код:
const name, age = "Kim", 22
fmt.Printf("%s is %d years old.\n", name, age)
// It is conventional not to worry about any
// error returned by Printf.
Вывод:
Kim is 22 years old.
func Println
func Println(a ...any) (n int, err error)
Println форматирует операнды с помощью форматов по умолчанию и записывает результат в стандартный вывод. Между операндами всегда добавляются пробелы, а в конце — перевод строки. Функция возвращает количество записанных байтов и любую возникшую ошибку записи.
Пример
Код:
const name, age = "Kim", 22 fmt.Println(name, "is", age, "years old.") // It is conventional not to worry about any // error returned by Println.
Вывод:
Kim is 22 years old.
func Scan
func Scan(a ...any) (n int, err error)
Scan сканирует текст, считанный со стандартного ввода, и сохраняет последовательные значения, разделённые пробелами, в последовательных аргументах. Переводы строк считаются пробелами. Функция возвращает количество успешно отсканированных элементов. Если оно меньше количества аргументов, err сообщит причину.
func Scanf
func Scanf(format string, a ...any) (n int, err error)
Scanf сканирует текст, считанный со стандартного ввода, и сохраняет последовательные значения, разделённые пробелами, в последовательных аргументах в соответствии с форматом. Функция возвращает количество успешно отсканированных элементов. Если оно меньше количества аргументов, err сообщит причину. Переводы строк во входных данных должны соответствовать переводам строк в формате. Единственное исключение: спецификатор %c всегда сканирует следующую руну во входных данных, даже если это пробел (или табуляция и т. п.) либо перевод строки.
func Scanln
func Scanln(a ...any) (n int, err error)
Scanln похожа на Scan, но прекращает сканирование при переводе строки; после последнего элемента должен следовать перевод строки или EOF.
func Sprint
func Sprint(a ...any) string
Sprint форматирует операнды с помощью форматов по умолчанию и возвращает полученную строку. Между операндами добавляются пробелы, если ни один из них не является строкой.
Пример
Код:
const name, age = "Kim", 22 s := fmt.Sprint(name, " is ", age, " years old.\n") io.WriteString(os.Stdout, s) // Ignoring error for simplicity.
Вывод:
Kim is 22 years old.
func Sprintf
func Sprintf(format string, a ...any) string
Sprintf форматирует данные согласно спецификатору формата и возвращает полученную строку.
Пример
Код:
const name, age = "Kim", 22
s := fmt.Sprintf("%s is %d years old.\n", name, age)
io.WriteString(os.Stdout, s) // Ignoring error for simplicity.
Вывод:
Kim is 22 years old.
func Sprintln
func Sprintln(a ...any) string
Sprintln форматирует операнды с помощью форматов по умолчанию и возвращает полученную строку. Между операндами всегда добавляются пробелы, а в конце — перевод строки.
Пример
Код:
const name, age = "Kim", 22 s := fmt.Sprintln(name, "is", age, "years old.") io.WriteString(os.Stdout, s) // Ignoring error for simplicity.
Вывод:
Kim is 22 years old.
func Sscan
func Sscan(str string, a ...any) (n int, err error)
Sscan сканирует строку-аргумент и сохраняет последовательные значения, разделённые пробелами, в последовательных аргументах. Переводы строк считаются пробелами. Функция возвращает количество успешно отсканированных элементов. Если оно меньше количества аргументов, err сообщит причину.
func Sscanf
func Sscanf(str string, format string, a ...any) (n int, err error)
Sscanf сканирует строку-аргумент и сохраняет последовательные значения, разделённые пробелами, в последовательных аргументах в соответствии с форматом. Функция возвращает количество успешно разобранных элементов. Переводы строк во входных данных должны соответствовать переводам строк в формате.
Пример
Код:
var name string
var age int
n, err := fmt.Sscanf("Kim is 22 years old", "%s is %d years old", &name, &age)
if err != nil {
panic(err)
}
fmt.Printf("%d: %s, %d\n", n, name, age)
Вывод:
2: Kim, 22
func Sscanln
func Sscanln(str string, a ...any) (n int, err error)
Sscanln похожа на Sscan, но прекращает сканирование при переводе строки; после последнего элемента должен следовать перевод строки или EOF.
type Formatter
Formatter реализуется любым значением, у которого есть метод Format. Реализация определяет, как интерпретируются State и руна, и может вызывать Sprint или Fprint(f) и т. д. для формирования вывода.
type Formatter interface {
Format(f State, verb rune)
} type GoStringer
GoStringer реализуется любым значением, у которого есть метод GoString, определяющий синтаксис Go для этого значения. Метод GoString используется для вывода значений, переданных в качестве операнда формата %#v.
type GoStringer interface {
GoString() string
} Пример
Код:
package fmt_test
import (
"fmt"
)
// Address has a City, State and a Country.
type Address struct {
City string
State string
Country string
}
// Person has a Name, Age and Address.
type Person struct {
Name string
Age uint
Addr *Address
}
// GoString makes Person satisfy the GoStringer interface.
// The return value is valid Go code that can be used to reproduce the Person struct.
func (p Person) GoString() string {
if p.Addr != nil {
return fmt.Sprintf("Person{Name: %q, Age: %d, Addr: &Address{City: %q, State: %q, Country: %q}}", p.Name, int(p.Age), p.Addr.City, p.Addr.State, p.Addr.Country)
}
return fmt.Sprintf("Person{Name: %q, Age: %d}", p.Name, int(p.Age))
}
func ExampleGoStringer() {
p1 := Person{
Name: "Warren",
Age: 31,
Addr: &Address{
City: "Denver",
State: "CO",
Country: "U.S.A.",
},
}
// If GoString() wasn't implemented, the output of `fmt.Printf("%#v", p1)` would be similar to
// Person{Name:"Warren", Age:0x1f, Addr:(*main.Address)(0x10448240)}
fmt.Printf("%#v\n", p1)
p2 := Person{
Name: "Theia",
Age: 4,
}
// If GoString() wasn't implemented, the output of `fmt.Printf("%#v", p2)` would be similar to
// Person{Name:"Theia", Age:0x4, Addr:(*main.Address)(nil)}
fmt.Printf("%#v\n", p2)
// Output:
// Person{Name: "Warren", Age: 31, Addr: &Address{City: "Denver", State: "CO", Country: "U.S.A."}}
// Person{Name: "Theia", Age: 4}
}
type ScanState
ScanState представляет состояние сканера, передаваемое пользовательским сканерам. Сканеры могут считывать данные по одной руне за раз или запросить ScanState найти следующий токен, разделённый пробелами.
type ScanState interface {
// ReadRune reads the next rune (Unicode code point) from the input.
// If invoked during Scanln, Fscanln, or Sscanln, ReadRune() will
// return EOF after returning the first '\n' or when reading beyond
// the specified width.
ReadRune() (r rune, size int, err error)
// UnreadRune causes the next call to ReadRune to return the same rune.
UnreadRune() error
// SkipSpace skips space in the input. Newlines are treated appropriately
// for the operation being performed; see the package documentation
// for more information.
SkipSpace()
// Token skips space in the input if skipSpace is true, then returns the
// run of Unicode code points c satisfying f(c). If f is nil,
// !unicode.IsSpace(c) is used; that is, the token will hold non-space
// characters. Newlines are treated appropriately for the operation being
// performed; see the package documentation for more information.
// The returned slice points to shared data that may be overwritten
// by the next call to Token, a call to a Scan function using the ScanState
// as input, or when the calling Scan method returns.
Token(skipSpace bool, f func(rune) bool) (token []byte, err error)
// Width returns the value of the width option and whether it has been set.
// The unit is Unicode code points.
Width() (wid int, ok bool)
// Because ReadRune is implemented by the interface, Read should never be
// called by the scanning routines and a valid implementation of
// ScanState may choose always to return an error from Read.
Read(buf []byte) (n int, err error)
} type Scanner
Scanner реализуется любым значением, у которого есть метод Scan. Этот метод сканирует входные данные, находя представление значения, и сохраняет результат в приёмнике, который должен быть указателем, чтобы это имело смысл. Метод Scan вызывается для любого аргумента Scan, Scanf или Scanln, реализующего этот интерфейс.
type Scanner interface {
Scan(state ScanState, verb rune) error
} type State
State представляет состояние принтера, передаваемое пользовательским форматировщикам. Оно предоставляет доступ к интерфейсу io.Writer, а также сведения о флагах и параметрах спецификатора формата операнда.
type State interface {
// Write is the function to call to emit formatted output to be printed.
Write(b []byte) (n int, err error)
// Width returns the value of the width option and whether it has been set.
Width() (wid int, ok bool)
// Precision returns the value of the precision option and whether it has been set.
Precision() (prec int, ok bool)
// Flag reports whether the flag c, a character, has been set.
Flag(c int) bool
} type Stringer
Stringer реализуется любым значением, у которого есть метод String, определяющий «естественный» формат этого значения. Метод String используется для вывода значений, переданных в качестве операнда любому формату, поддерживающему строку, или принтеру без форматирования, например Print.
type Stringer interface {
String() string
} Пример
Код:
package fmt_test
import (
"fmt"
)
// Animal has a Name and an Age to represent an animal.
type Animal struct {
Name string
Age uint
}
// String makes Animal satisfy the Stringer interface.
func (a Animal) String() string {
return fmt.Sprintf("%v (%d)", a.Name, a.Age)
}
func ExampleStringer() {
a := Animal{
Name: "Gopher",
Age: 2,
}
fmt.Println(a)
// Output: Gopher (2)
}
© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/fmt/