A reference page for Go’s fmt package. The Language Basics section already introduced the five verbs you’ll use 90% of the time (%v, %d, %s, %f, %T). Come back here whenever you need to:

  • format numbers to a fixed width or a specific number of decimal places
  • print integers in binary, octal, or hex
  • dump a struct with its field names while debugging
  • build a string with Sprintf instead of printing it

The three families

Every printing function in fmt belongs to one of three families:

FamilyWhere it writesExamples
Print...Standard output, no formatting verbsPrint, Println
Printf...Standard output, with formatting verbsPrintf
Sprintf...Returns a string instead of printingSprint, Sprintln, Sprintf

There are also Fprint* (writes to any io.Writer, like a file) and Errorf (builds an error), but you’ll meet those later.

package main

import "fmt"

func main() {
    name := "Manikandan"
    age := 30

    fmt.Print("Hello, ", name, "\n")           // no newline, no spaces between args
    fmt.Println("Hello,", name)                 // adds spaces + newline
    fmt.Printf("Hello, %s! You are %d.\n", name, age) // formatted
    s := fmt.Sprintf("user=%s age=%d", name, age)     // builds a string
    fmt.Println(s)
}
Hello, Manikandan
Hello, Manikandan
Hello, Manikandan! You are 30.
user=Manikandan age=30

The rest of this lesson focuses on Printf and its verbs, because that’s where all the power lives.

The %v verb — when in doubt, use this

%v prints any value in its default format. It’s the verb you’ll use most often:

// inside main()
fmt.Printf("%v\n", 42)        // 42
fmt.Printf("%v\n", 3.14)      // 3.14
fmt.Printf("%v\n", "hello")   // hello
fmt.Printf("%v\n", true)      // true
fmt.Printf("%v\n", []int{1, 2, 3}) // [1 2 3]

Two close cousins are useful when debugging:

  • %+v — for structs, also prints field names
  • %#v — prints a Go-syntax representation (the value as you’d write it in code)
  • %T — prints the type of the value, not the value itself
// inside main()
type User struct {
    Name string
    Age  int
}

u := User{Name: "Manikandan", Age: 30}

fmt.Printf("%v\n", u)   // {Manikandan 30}
fmt.Printf("%+v\n", u)  // {Name:Manikandan Age:30}
fmt.Printf("%#v\n", u)  // main.User{Name:"Manikandan", Age:30}
fmt.Printf("%T\n", u)   // main.User

Reach for %+v when a Println of a struct is hard to read — it’s the quickest way to see what’s inside without writing custom code.

Verbs by type

Strings and bytes

VerbDescriptionExample output
%sThe raw stringhello
%qDouble-quoted, escaped"hello"
%xHex, lowercase68656c6c6f
%XHex, uppercase68656C6C6F
// inside main()
s := "hello"
fmt.Printf("%s\n", s) // hello
fmt.Printf("%q\n", s) // "hello"
fmt.Printf("%x\n", s) // 68656c6c6f

Integers

VerbDescriptionExample output
%dBase 10 (decimal)255
%bBase 2 (binary)11111111
%oBase 8 (octal)377
%xBase 16, lowercaseff
%XBase 16, uppercaseFF
%cThe Unicode character at that code pointA (for 65)
%qQuoted character literal'A'
%UUnicode notationU+0041
// inside main()
n := 255
fmt.Printf("%d %b %o %x %X\n", n, n, n, n, n)
// 255 11111111 377 ff FF

r := 'A'
fmt.Printf("%c %q %U\n", r, r, r)
// A 'A' U+0041

Floats

VerbDescriptionExample output
%fDecimal, no exponent3.141590
%eScientific (lowercase)3.141590e+00
%EScientific (uppercase)3.141590E+00
%g%e for large exponents, %f otherwise3.14159
%G%E for large exponents, %F otherwise3.14159
// inside main()
pi := 3.14159
fmt.Printf("%f %e %g\n", pi, pi, pi)
// 3.141590 3.141590e+00 3.14159

Booleans

VerbDescription
%tThe word true or false

Pointers

VerbDescriptionExample output
%pAddress in hex, with leading 0x0xc0000180a0

Width and precision

You can control how much space a value takes up by putting a number between the % and the verb:

// inside main()
fmt.Printf("|%5d|\n", 42)    // |   42|   width 5, right-aligned (default)
fmt.Printf("|%-5d|\n", 42)   // |42   |   width 5, left-aligned
fmt.Printf("|%05d|\n", 42)   // |00042|   width 5, zero-padded

For floats, precision goes after a dot:

// inside main()
pi := 3.14159

fmt.Printf("|%f|\n", pi)     // |3.141590|     default precision (6)
fmt.Printf("|%.2f|\n", pi)   // |3.14|         2 digits after the dot
fmt.Printf("|%8.2f|\n", pi)  // |    3.14|     width 8, precision 2
fmt.Printf("|%-8.2f|\n", pi) // |3.14    |     width 8, left-aligned

Width and precision work for strings too — precision truncates:

// inside main()
fmt.Printf("|%10s|\n", "hi")   // |        hi|
fmt.Printf("|%-10s|\n", "hi")  // |hi        |
fmt.Printf("|%.3s|\n", "hello") // |hel|       precision truncates strings

Flag characters

A handful of flags go between % and the verb to tweak output:

FlagEffect
+Always print a sign on numbers (+42, -42); for %q, ASCII-only output
-Left-justify within the field width
#Alternate format: 0 prefix for %#o, 0x for %#x, raw string for %#q
0Pad numbers with leading zeros instead of spaces
(space)Leave a space for the sign of positive numbers (% d 42)
// inside main()
fmt.Printf("%+d\n", 42)   // +42
fmt.Printf("%#x\n", 255)  // 0xff
fmt.Printf("%05d\n", 42)  // 00042

Defaults used by %v

%v picks a default verb based on the value’s type:

TypeDefault verb
bool%t
int, int8, …%d
uint, uint8, …%d (or %x with %#v)
float, complex%g
string%s
chan, pointer%p

So Println(x) is roughly Printf("%v\n", x). That’s why you’ve been able to print everything so far without thinking about verbs.

The escape hatch: %%

If you want a literal % in your output, write %%:

// inside main()
fmt.Printf("100%% done\n") // 100% done

A practical example

Putting it together:

package main

import "fmt"

type Product struct {
    Name  string
    Price float64
    Stock int
}

func main() {
    items := []Product{
        {"Pencil", 1.5, 120},
        {"Notebook", 12.99, 14},
        {"Eraser", 0.75, 300},
    }

    fmt.Printf("%-10s %8s %6s\n", "NAME", "PRICE", "STOCK")
    fmt.Printf("%-10s %8s %6s\n", "----", "-----", "-----")
    for _, p := range items {
        fmt.Printf("%-10s %8.2f %6d\n", p.Name, p.Price, p.Stock)
    }
}
NAME          PRICE  STOCK
----          -----  -----
Pencil         1.50    120
Notebook      12.99     14
Eraser         0.75    300

Three column widths, left-aligned text, two-decimal currency — all in three Printf calls.

Quick verb reference

A condensed version you can keep open while coding:

VerbUse it for
%vAnything — default format
%+vStruct with field names
%#vGo-syntax representation
%TThe type of the value
%dInteger (base 10)
%b %o %x %XInteger in binary / octal / hex
%c %q %URune as character / quoted / Unicode
%f %e %gFloat with decimals / scientific / compact
%.2fFloat with 2 decimal places
%s %qString raw / quoted
%tBoolean
%pPointer address
%%A literal %

For the complete list, the fmt package docs are the source of truth.

Toggle theme (T)