env.dev

Go (Golang) Cheat Sheet — Quick Reference

Go quick reference: types, structs, interfaces, goroutines, channels, error handling, slices, maps, and defer/panic/recover.

By env.dev Updated

A quick reference for Go (Golang) syntax and patterns. Covers types, variables, structs, interfaces, goroutines, channels, error handling, slices, maps, and defer/panic/recover. Current through Go 1.26 (February 2026), which let new() take an expression and made the Green Tea garbage collector the default.

Types & Variables

SyntaxDescription
var x intDeclare variable with explicit type
var x int = 42Declare and initialize
x := 42Short variable declaration (inferred type)
const Pi = 3.14Constant declaration
int, int8, int16, int32, int64Signed integer types
uint, uint8 (byte), uint16, ..Unsigned integer types
float32, float64Floating point types
stringImmutable UTF-8 string
boolBoolean (true / false)
runeUnicode code point (alias for int32)

Structs

SyntaxDescription
type User struct { Name string }Define a struct type
u := User{Name: "Alice"}Create struct instance
u := User{}Zero-value struct
u.NameAccess struct field
type Admin struct { User; Level int }Embedded struct (composition)
func (u User) String() stringMethod with value receiver — gets a copy, cannot mutate
func (u *User) SetName(n string)Method with pointer receiver — use when mutating or for large structs
type Point struct { X, Y float64 }Multiple fields of same type

Interfaces

SyntaxDescription
type Reader interface { Read([]byte) }Define an interface
interface{}Empty interface (accepts any value)
anyAlias for interface{} (Go 1.18+)
v, ok := i.(string)Type assertion with check
switch v := i.(type) { case string: }Type switch
type ReadWriter interface { Reader; Writer }Compose interfaces via embedding
var w io.Writer = &bufImplicit interface satisfaction

Slices & Maps

SyntaxDescription
s := []int{1, 2, 3}Slice literal
s := make([]int, 0, 10)Make slice with length 0, capacity 10
s = append(s, 4, 5)Append elements to slice
s[1:3]Sub-slice (index 1 to 2)
len(s), cap(s)Length and capacity
copy(dst, src)Copy elements between slices
m := map[string]int{"a": 1}Map literal
m := make(map[string]int)Make empty map
v, ok := m["key"]Map lookup with existence check
delete(m, "key")Delete key from map

Goroutines

SyntaxDescription
go f()Launch function as goroutine
go func() { .. }()Launch anonymous goroutine
runtime.NumGoroutine()Get number of running goroutines
sync.WaitGroupWait for group of goroutines to finish
wg.Add(1)Increment WaitGroup counter
wg.Done()Decrement WaitGroup counter
wg.Wait()Block until counter reaches zero
sync.Mutex / sync.RWMutexMutual exclusion locks

Channels

SyntaxDescription
ch := make(chan int)Unbuffered channel — send blocks until someone receives
ch := make(chan int, 10)Buffered channel (capacity 10) — send blocks only when full
ch <- 42Send value to channel
v := <-chReceive value from channel
close(ch)Close channel (no more sends)
for v := range ch { }Iterate until channel closed
select { case v := <-ch: .. }Wait on multiple channels
ch := make(chan<- int)Send-only channel type
ch := make(<-chan int)Receive-only channel type

Error Handling

PatternDescription
if err != nil { return err }Standard error check and propagate
fmt.Errorf("wrap: %w", err)Wrap error with context (Go 1.13+)
errors.Is(err, target)Check if err matches target (unwraps)
errors.As(err, &target)Extract typed error from chain
errors.New("message")Create simple error value
type MyErr struct { .. }Custom error type (implement Error())
var ErrNotFound = errors.New(..)Sentinel error variable

Defer, Panic & Recover

SyntaxDescription
defer f()Schedule call to run when function returns
defer file.Close()Common: close resource on exit
defer mu.Unlock()Common: release lock on exit
panic("message")Trigger runtime panic (unwind stack)
recover()Catch panic in deferred function
defer func() { if r := recover(); r != nil { .. } }()Full recover pattern

Common gotchas

  • Loop variables are per-iteration since Go 1.22 (February 2024) — the classic go func() { use(v) }() capture bug is fixed, but only when go.mod declares go 1.22 or later. Older module directives keep the old shared-variable semantics.
  • Reading from a nil map returns the zero value; writing to one panics. var m map[string]int is nil — initialize with make or a literal before assigning.
  • append may reuse the backing array: two slices from the same source can silently overwrite each other's elements while capacity remains. Force a copy with slices.Clone (Go 1.21+) when handing a sub-slice out.
  • defer runs at function exit, not block exit — deferring f.Close() inside a loop accumulates open handles until the function returns.
  • A goroutine blocked forever on a channel send is a leak. Go 1.26 ships an experimental goroutineleak pprof profile (GOEXPERIMENT=goroutineleakprofile) that finds them via the garbage collector.

Related: environment variables in Go and constants in Go (untyped constants and iota get their own gotcha list).

Was this helpful?

Frequently Asked Questions

What is a goroutine?

A goroutine is a lightweight thread managed by the Go runtime. Start one with the go keyword: go myFunction(). Goroutines are multiplexed onto OS threads and are very cheap to create (a few KB of stack).

How does error handling work in Go?

Go uses explicit error returns instead of exceptions. Functions return an error value as the last return: val, err := doSomething(). Check if err != nil to handle errors.

What is the difference between slices and arrays?

Arrays have a fixed size and are value types. Slices are dynamically-sized views into arrays, are reference types, and are the more common choice. Create slices with make([]T, len, cap) or slice literals.