The Go fmt package formats values with verbs — a percent sign followed by
a letter — that control how each argument is rendered. Choosing the wrong verb
gives misleading output or an explicit error placeholder. This tool is a
searchable reference of every common verb with its accepted types and a worked
example.
How it works
fmt.Printf, Sprintf, and friends scan the format string and pair each verb
with the next argument. Each verb has a default behaviour plus optional flags,
width, and precision that refine it. The reference groups verbs by purpose:
- General —
%v(default),%+v(with field names),%#v(Go syntax),%T(type),%%(literal percent). - Integers —
%d(decimal),%b(binary),%o(octal),%x/%X(hex),%c(rune),%U(Unicode). - Floats —
%f/%F,%e/%E(scientific),%g/%G(compact). - Strings/bytes —
%s,%q(quoted),%x(hex bytes). - Boolean —
%t. - Pointer —
%p.
Worked example
type User struct{ Name string; Age int }
u := User{"Ada", 36}
fmt.Printf("%v\n", u) // {Ada 36}
fmt.Printf("%+v\n", u) // {Name:Ada Age:36}
fmt.Printf("%#v\n", u) // main.User{Name:"Ada", Age:36}
fmt.Printf("%T\n", u) // main.User
fmt.Printf("%6.2f\n", 3.14159) // " 3.14"
fmt.Printf("%q\n", "hi\n") // "hi\n"
Notes
- Flags:
+always shows a sign,(space) leaves a space for the sign of positive numbers,-left-justifies,0pads with leading zeros,#enables the alternate form (0xprefix for%#x, etc.). - Width and precision can be supplied dynamically with
*, taking the value from the argument list, as infmt.Printf("%*d", 5, n). - A type mismatch produces a visible placeholder such as
%!d(string=hi)instead of a panic, so bugs surface in the output.
Choosing the right verb
For structs
%v is fine for quick debugging. Use %+v when you need to know which field is which — it adds field names. Use %#v when you want output that compiles, for example in a test expectation or a generated file.
type Point struct{ X, Y int }
p := Point{3, 4}
fmt.Printf("%v\n", p) // {3 4}
fmt.Printf("%+v\n", p) // {X:3 Y:4}
fmt.Printf("%#v\n", p) // main.Point{X:3, Y:4}
For integers
Use %d for ordinary decimal output. %x is the fastest way to get a hex representation — useful for hashes, memory addresses, and byte inspection. %b outputs binary, handy when working with bitmasks and flags. %c converts an integer to its Unicode rune character, useful for ASCII and emoji manipulation.
n := 255
fmt.Printf("%d %x %b %c\n", n, n, n, n) // 255 ff 11111111 ÿ
For floats
%f is the everyday verb for fixed-point notation. %e writes scientific notation, useful in scientific computing outputs. %g picks the more compact of %e and %f automatically — a good default when you do not know the scale in advance.
For strings — %s vs %q
%s prints the string exactly as stored. %q surrounds it in double quotes and escapes control characters and non-printable bytes. Always prefer %q in log lines and error messages where whitespace or newlines inside a value would otherwise be invisible.
s := "line one\nline two"
fmt.Printf("%s\n", s) // prints across two lines — may look like log corruption
fmt.Printf("%q\n", s) // "line one\nline two" — clearly one log record
Width and precision quick reference
| Verb example | Effect |
|---|---|
%6d | Pad integer to at least 6 characters |
%-6d | Left-justify in 6-character field |
%06d | Pad with leading zeros |
%6.2f | Float: 6 wide, 2 decimal places |
%.5s | Truncate string to 5 characters |
%*d | Width from next argument |