Skip to content

Go Cheatsheet · Golang Reference — Goroutines, Channels, Slices

Last verified May 2026 — runs in your browser
Go Cheatsheet
var x int = 10

Variable with explicit type

Basics
x := 10

Short variable declaration (inferred)

Basics
const Pi = 3.14159

Constant declaration

Basics
int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64

Integer types

Basics
float32 float64

Floating point types

Basics
string bool byte rune

Other basic types

Basics
if x > 0 { ... } else if x == 0 { ... } else { ... }

If/else (no parentheses needed)

Basics
for i := 0; i < 10; i++ { ... }

Classic for loop

Basics
for _, v := range slice { ... }

Range over slice/map/string

Basics
for condition { ... }

While-style loop

Basics
for { ... }

Infinite loop

Basics
switch x { case 1: ... case 2, 3: ... default: ... }

Switch (no fallthrough by default)

Basics
fmt.Println("hello")

Print with newline

Basics
fmt.Sprintf("name: %s, age: %d", name, age)

Format string

Basics
strconv.Atoi(s) / strconv.Itoa(n)

String <-> int conversion

Basics
s := []int{1, 2, 3}

Create a slice literal

Slices & Maps
s := make([]int, 0, 10)

Create slice with length and capacity

Slices & Maps
s = append(s, 4, 5)

Append elements to slice

Slices & Maps
s[1:3]

Slice of slice (index 1 to 2)

Slices & Maps
len(s) / cap(s)

Length and capacity of slice

Slices & Maps
copy(dst, src)

Copy elements between slices

Slices & Maps
s = append(s[:i], s[i+1:]...)

Delete element at index i

Slices & Maps
sort.Ints(s) / sort.Strings(s)

Sort slice in-place

Slices & Maps
slices.Contains(s, val)

Check if slice contains value (Go 1.21+)

Slices & Maps
m := map[string]int{"a": 1}

Create a map literal

Slices & Maps
m := make(map[string]int)

Create empty map

Slices & Maps
m["key"] = value

Set map value

Slices & Maps
val, ok := m["key"]

Get value with existence check

Slices & Maps
delete(m, "key")

Delete key from map

Slices & Maps
for k, v := range m { ... }

Iterate over map entries

Slices & Maps
func add(a, b int) int { return a + b }

Function with return type

Functions
func divide(a, b float64) (float64, error)

Multiple return values

Functions
func greet(name string, opts ...string)

Variadic function

Functions
result, err := divide(10, 3)

Capture multiple returns

Functions
fn := func(x int) int { return x * 2 }

Anonymous function / closure

Functions
defer file.Close()

Defer execution until function returns

Functions
func init() { ... }

Package initialization function

Functions
type User struct { Name string Age int }

Struct type definition

Structs
u := User{Name: "Alice", Age: 30}

Struct literal

Structs
u := &User{Name: "Alice"}

Pointer to struct

Structs
func (u User) Greet() string { return "Hi " + u.Name }

Method on struct (value receiver)

Structs
func (u *User) SetName(n string) { u.Name = n }

Method with pointer receiver (mutate)

Structs
type Admin struct { User Role string }

Struct embedding (composition)

Structs
type Config struct { Host string `json:"host"` }

Struct tags (JSON, DB, etc.)

Structs
type Reader interface { Read(p []byte) (n int, err error) }

Interface definition

Interfaces
type Stringer interface { String() string }

Stringer interface (like toString)

Interfaces
interface{} / any

Empty interface (accepts any type)

Interfaces
val, ok := i.(ConcreteType)

Type assertion with check

Interfaces
switch v := i.(type) { case string: ... case int: ... }

Type switch

Interfaces
go func() { ... }()

Launch goroutine

Concurrency
ch := make(chan int)

Create unbuffered channel

Concurrency
ch := make(chan int, 10)

Create buffered channel (cap 10)

Concurrency
ch <- value

Send value to channel

Concurrency
value := <-ch

Receive value from channel

Concurrency
close(ch)

Close channel (no more sends)

Concurrency
select { case v := <-ch1: ... case ch2 <- val: ... default: ... }

Select on multiple channels

Concurrency
var mu sync.Mutex mu.Lock() defer mu.Unlock()

Mutex for shared state

Concurrency
var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() ... }() wg.Wait()

WaitGroup for goroutine coordination

Concurrency
if err != nil { return fmt.Errorf("failed: %w", err) }

Wrap and propagate error

Error Handling
errors.New("something failed")

Create simple error

Error Handling
fmt.Errorf("user %d: %w", id, err)

Create formatted error (wrapping)

Error Handling
errors.Is(err, target)

Check if error matches target

Error Handling
errors.As(err, &target)

Extract typed error from chain

Error Handling
type MyError struct { Code int Msg string } func (e *MyError) Error() string { return e.Msg }

Custom error type

Error Handling
panic("fatal") / recover()

Panic and recover (rare, avoid)

Error Handling
Showing 65 of 65 snippets

Go (Golang) Cheat Sheet — Goroutines, Channels, Interfaces & Error Handling

Go appeared in 2009 with an explicit aim of staying small — short keyword list, gofmt-enforced style, a concurrency model built around goroutines and channels. The cheatsheet below covers 60+ snippets across basics, slices and maps, functions, structs, interfaces, concurrency, and error handling. Most trouble in Go code does not come from forgetting syntax. It comes from quirks that look ordinary until they bite. An interface value holding a typed nil pointer is itself not nil, so `if err != nil` returns true on an `err` assigned `var p *MyError; return p` — the interface still carries the type. A slice and its `append` may share the same backing array or not depending on capacity, so appending to a passed slice can mutate the caller's data or quietly stop reflecting it. Map iteration order is deliberately randomised between runs, so a test depending on insertion order passes nine times and fails on the tenth. These are the snippets pulled up while debugging that — the right nil check, the right append pattern, the right channel direction — without rereading the spec each time.

Common pitfalls in Go

A few patterns earn their place near the top of any Go file. Return `nil` explicitly when there is no error rather than a typed nil through an interface, because `return (*MyError)(nil)` against an `error` return type produces a non-nil interface that bypasses `if err != nil` checks downstream. Wrap propagated errors with `fmt.Errorf("context: %w", err)` so callers can later use `errors.Is` and `errors.As` to inspect the chain — a plain `%v` loses that information forever. `defer` evaluates its arguments at the point the `defer` statement runs, not when the deferred call actually fires, so `defer log.Print(time.Now())` logs the start time and not the end. The `for _, v := range slice` loop reuses the same `v` variable across iterations, which is fine until a goroutine captures it by reference inside the loop (Go 1.22 made each iteration get its own scope, but pre-1.22 code still in production needs the explicit `v := v` shadow). The cheatsheet groups all of this into Basics, Slices & Maps, Functions, Structs, Interfaces, Concurrency, and Error Handling so the right section is one click away.

  • 60+ practical Go snippets
  • 7 categories from basics to concurrency
  • Goroutines and channels explained
  • Error handling patterns
  • One-click copy to clipboard
  • Struct methods and interfaces covered

Free. No signup. Your inputs stay in your browser. Ads via Google AdSense (consent required).