Пакет fmt
Обзор
Пакет fmt реализует форматированный ввод/вывод с функциями, аналогичными функциям C printf и scanf. Форматные «глаголы» взяты из C, но они проще.
Вывод
Глаголы:
Общие:
%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 character 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
Строки и срезы байтов (обрабатываются одинаково с помощью этих глаголов):
%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
Ширина и точность измеряются в единицах кодовых точек Юникода, то есть рунах. (Это отличается от C printf, где единицы всегда измеряются в байтах.) Любой или оба флага могут быть заменены символом '*', что приводит к получению их значений из следующего операнда (предшествующего форматируемому), который должен быть типа 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 по умолчанию каждый форматный глагол форматирует последовательные аргументы, переданные в вызове. Однако обозначение [n] непосредственно перед глаголом указывает, что вместо этого должен быть отформатирован n-ый аргумент (индексированный с 1). Такое же обозначение перед '*' для ширины или точности выбирает индекс аргумента, содержащий значение. После обработки выражения в квадратных скобках [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 вызывает panic при вызове процедурой вывода, пакет fmt переформатирует сообщение об ошибке из panic, украсив его указанием, что оно пришло через пакет fmt. Например, если метод String вызывает panic("bad"), результирующее отформатированное сообщение будет выглядеть так
%!s(PANIC=bad)
Просто %!s показывает глагол вывода, используемый при возникновении ошибки. Однако, если вызов panic вызван отсутствием приемника в методе Error или String, вывод представляет собой неотформатированную строку «<nil>».
Сканирование
Аналогичный набор функций сканирует отформатированный текст для получения значений. 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-пробела, кроме новой строки.
В строке формата глагол, введенный символом %, потребляет и анализирует входные данные; эти глаголы описаны более подробно ниже. Любой символ, кроме %, пробела или новой строки в формате, потребляет ровно этот символ, который должен присутствовать. Новая строка с нулем или более пробелами перед ней в строке формата потребляет ноль или более пробелов во входных данных, за которыми следует одна новая строка или конец входных данных. Пробел после новой строки в строке формата потребляет ноль или более пробелов во входных данных. В противном случае любой набор из одного или более пробелов в строке формата потребляет максимально возможное количество пробелов во входных данных. Если набор пробелов в строке формата не прилегает к новой строке, он должен потреблять как минимум один пробел из входных данных или найти конец входных данных.
Обработка пробелов и новых строк отличается от обработки C-семейства scanf: в 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, считывающий в строку) прекращает потреблять входные данные при первой встреченной пробеле или новой строке.
Обычные префиксы для задания основания 0b (двоичный), 0o и 0 (восьмеричный) и 0x (шестнадцатеричный) принимаются при сканировании целых чисел без формата или с глаголом %v, как и разделители цифр подчёркивания.
Ширина интерпретируется в тексте входных данных, но нет синтаксиса для сканирования с точностью (нет %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 и т. д. могут считывать один символ (rune) за пределами считанного ввода, что означает, что цикл, вызывающий процедуру сканирования, может пропустить часть входных данных. Это обычно проблема только тогда, когда между входными значениями нет пробелов. Если читатель, предоставленный Fscan, реализует метод ReadRune, этот метод будет использоваться для чтения символов. Если читатель также реализует метод UnreadRune, этот метод будет использоваться для сохранения символа, и последующие вызовы не потеряют данные. Чтобы добавить методы ReadRune и UnreadRune к читателю, не обладающему этой возможностью, используйте bufio.NewReader.
Пример (Форматы)
Эти примеры демонстрируют основы вывода с использованием строки формата. Printf, Sprintf и Fprintf все принимают строку формата, которая определяет, как отформатировать последующие аргументы. Например, %d (мы называем это «глаголом») указывает на вывод соответствующего аргумента, который должен быть целым числом (или чем-то, содержащим целое число, например, слайсом целых чисел) в десятичной форме. Глагол %v («v» для «значения») всегда форматирует аргумент в его стандартной форме, так же, как Print или Println. Специальный глагол %T («T» для «Тип») выводит тип аргумента вместо его значения. Примеры не исчерпывающие; см. комментарий к пакету для получения всех подробностей.
Код:
%%%CODE_BLOCK_23%%Вывод:
%%%CODE_BLOCK_24%%Пример (Вывод)
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)
Вывод:
%%%CODE_BLOCK_26%%Индекс
Примеры
Файлы пакета
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) error
Errorf форматирует согласно спецификатору формата и возвращает строку в качестве значения, удовлетворяющего интерфейсу error.
Если спецификатор формата содержит глагол %w с аргументом-ошибкой, возвращаемая ошибка будет реализовывать метод 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)
}
Вывод:
%%%CODE_BLOCK_49%% %%%CODE_BLOCK_50%%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
%%%CODE_BLOCK_60%%Функция Scanf сканирует текст, считываемый со стандартного ввода, сохраняя последовательные разделенные пробелом значения в последовательные аргументы, как определено форматом. Она возвращает количество успешно отсканированных элементов. Если это значение меньше количества аргументов, err сообщит причину. Переводы строк в входных данных должны соответствовать переводам строк в формате. Единственное исключение: глагол %c всегда сканирует следующий символ ввода, даже если это пробел (или табуляция и т. д.) или перевод строки.
func Scanln
func Scanln(a ...any) (n int, err error)
Функция Scanln аналогична функции Scan, но останавливается при чтении перевода строки и после последнего элемента должна быть перевод строки или конец файла.
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, но останавливается при чтении перевода строки и после последнего элемента должна быть перевод строки или конец файла.
type Formatter
Formatter реализуется любым значением, имеющим метод Format. Реализация контролирует, как State и rune интерпретируются, и может вызывать 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/