Learn Go

Go Cheat Sheets

Quick-reference guides for Go syntax, the standard library, and common idioms.

Variables, Constants & iota

// Variable declarations
var x int = 42
var s string // zero value: ""
var b bool   // zero value: false
 
// Short declaration (inside functions only)
y := 3.14
name, age := "Alice", 30
 
// Constants
const Pi = 3.14159
const MaxSize = 1 << 20 // 1 MB
 
// iota in a const block
type Direction int
const (
	North Direction = iota // 0
	East                   // 1
	South                  // 2
	West                   // 3
)
 
type ByteSize float64
const (
	_           = iota // discard first value
	KB ByteSize = 1 << (10 * iota) // 1024
	MB                              // 1048576
	GB
)

Functions

// Multiple return values
func divide(a, b float64) (float64, error) {
	if b == 0 {
		return 0, errors.New("division by zero")
	}
	return a / b, nil
}
 
// Named return values
func minMax(nums []int) (min, max int) {
	min, max = nums[0], nums[0]
	for _, n := range nums[1:] {
		if n < min { min = n }
		if n > max { max = n }
	}
	return // naked return
}
 
// Variadic function
func sum(ns ...int) int {
	total := 0
	for _, n := range ns {
		total += n
	}
	return total
}
sum(1, 2, 3)
nums := []int{1, 2, 3}
sum(nums...) // spread slice
 
// Closure
func counter() func() int {
	n := 0
	return func() int {
		n++
		return n
	}
}
c := counter()
c() // 1
c() // 2

Control Flow

// for — the only loop keyword
for i := 0; i < 10; i++ { }
for i < 10 { }            // while equivalent
for { }                   // infinite loop
for i, v := range slice { }
for k, v := range m { }  // map
for ch := range channel { } // receive until closed
 
// if / else
if x > 0 {
	fmt.Println("positive")
} else if x < 0 {
	fmt.Println("negative")
} else {
	fmt.Println("zero")
}
 
// if with initialiser
if err := doWork(); err != nil {
	log.Fatal(err)
}
 
// switch — no fallthrough by default
switch x {
case 1:
	fmt.Println("one")
case 2, 3:
	fmt.Println("two or three")
default:
	fmt.Println("other")
}
 
// switch on type (type switch)
switch v := i.(type) {
case int:
	fmt.Printf("int: %d\n", v)
case string:
	fmt.Printf("string: %s\n", v)
default:
	fmt.Printf("unknown: %T\n", v)
}
 
// select — for channels
select {
case msg := <-ch:
	fmt.Println(msg)
case ch <- "hello":
	fmt.Println("sent")
default:
	fmt.Println("no channel ready")
}

Types: Arrays, Slices, Maps, Structs

// Array — fixed size
var a [3]int               // [0 0 0]
b := [3]int{1, 2, 3}
c := [...]int{1, 2, 3}    // compiler counts
 
// Slice — dynamic view of an array
s := []int{1, 2, 3}
s = append(s, 4, 5)
s2 := s[1:3]              // [2 3] — shares memory
cp := make([]int, 5)      // len=5, cap=5
copy(cp, s)
 
// Map
m := map[string]int{"a": 1, "b": 2}
m["c"] = 3
v, ok := m["x"]           // ok=false if missing
delete(m, "a")
 
// Struct
type Person struct {
	Name string
	Age  int
}
p := Person{Name: "Alice", Age: 30}
p.Age = 31
pp := &Person{Name: "Bob"} // pointer to struct
 
// Embedded struct
type Employee struct {
	Person             // promoted fields
	Company string
}
e := Employee{Person: Person{Name: "Carol"}, Company: "Gophers Inc."}
fmt.Println(e.Name)   // e.Person.Name promoted
 
// Interface
type Stringer interface {
	String() string
}
var s Stringer = p     // if Person has String() string method

Pointers

x := 42
p := &x          // pointer to x
*p = 100         // dereference to update x
fmt.Println(x)   // 100
 
// Pointer receiver — mutates the value
func (p *Person) Birthday() {
	p.Age++
}
 
// new — allocates zeroed value, returns pointer
n := new(int)    // *int, *n == 0