Skip to main content

Comprehensive Go language cheatsheet, written to be something you can actually keep open while coding. It includes core syntax, language rules, standard patterns, and essential "Go-isms".

---
title: Go (Golang) Language Cheatsheet
subtitle: Comprehensive Go language cheatsheet, written to be something you can actually keep open while coding.
author: Jon LaBelle
date: February 1, 2026
source: https://jonlabelle.com/snippets/view/markdown/go-golang-language-cheatsheet
---

Comprehensive Go language cheatsheet, written to be something you can actually keep open while coding.

It includes core syntax, language rules, standard patterns, and essential “Go-isms”.

---

## Table of Contents

1. [Program Structure](#program-structure)
2. [Variables & Constants](#variables--constants)
3. [Primitive Types](#primitive-types)
4. [Operators](#operators)
5. [Control Flow](#control-flow)
6. [Functions](#functions)
7. [Pointers](#pointers)
8. [Arrays](#arrays)
9. [Slices](#slices)
10. [Maps](#maps)
11. [Structs](#structs)
12. [Methods & Receivers](#methods--receivers)
13. [Interfaces](#interfaces)
14. [Generics](#generics)
15. [Error Handling](#error-handling)
16. [`defer`, `panic`, `recover`](#defer-panic-recover)
17. [Concurrency](#concurrency)
18. [Channels](#channels)
19. [Packages & Modules](#packages--modules)
20. [Visibility & Naming](#visibility--naming)
21. [Memory & Zero Values](#memory--zero-values)
22. [Common Gotchas](#common-gotchas)
23. [Idiomatic Go Rules](#idiomatic-go-rules)

---

## Program Structure

```go
package main

import "fmt"

func main() {
    fmt.Println("Hello, Go")
}
```

- Every executable has `package main`
- Entry point is `func main()`
- Imports are explicit

---

## Variables & Constants

### Short Declaration

```go
x := 10
```

### Explicit Declaration

```go
var x int = 10
var y = 20
var z int
```

### Constants

```go
const Pi = 3.14
const (
    A = 1
    B = 2
)
```

- Constants are compile-time
- No `const` slices, maps, or structs

---

## Primitive Types

### Numeric

```go
int, int8, int16, int32, int64
uint, uint8, uint16, uint32, uint64
float32, float64
complex64, complex128
```

### Aliases

```go
byte // uint8
rune // int32 (Unicode)
```

### Other

```go
bool
string
```

---

## Operators

### Arithmetic

```go
+  -  *  /  %
```

### Comparison

```go
==  !=  <  <=  >  >=
```

### Logical

```go
&&  ||  !
```

### Bitwise

```go
&  |  ^  <<  >>  &^
```

### Assignment

```go
=  +=  -=  *=  /=  %=
```

- ❌ No ternary operator
- ❌ No operator overloading

---

## Control Flow

### If

```go
if x > 0 {
}
```

With initializer:

```go
if v := get(); v > 0 {
}
```

---

### For (only loop)

```go
for i := 0; i < 10; i++ {}
for condition {}
for {}
```

Range:

```go
for i, v := range slice {}
for k, v := range map {}
```

---

### Switch

```go
switch x {
case 1:
case 2:
default:
}
```

Type switch:

```go
switch v := x.(type) {
case int:
case string:
}
```

---

## Functions

```go
func add(a int, b int) int {
    return a + b
}
```

### Multiple Returns

```go
func f() (int, error) {
    return 0, nil
}
```

### Named Returns

```go
func f() (result int) {
    result = 10
    return
}
```

---

## Pointers

```go
var x int
p := &x
fmt.Println(*p)
```

- No pointer arithmetic
- Used for mutation & performance
- Methods often use pointer receivers

---

## Arrays

```go
var a [3]int
b := [3]int{1,2,3}
```

- Fixed length
- Value types
- Rarely used directly

---

## Slices

```go
s := []int{1,2,3}
s = append(s, 4)
```

### Slice Expressions

```go
s[low:high]
```

### Copy

```go
dst := make([]int, len(src))
copy(dst, src)
```

⚠️ Slices share backing arrays

---

## Maps

```go
m := map[string]int{
    "a": 1,
}
```

Lookup:

```go
v, ok := m["a"]
```

Delete:

```go
delete(m, "a")
```

- Reference type
- Not thread-safe
- Iteration order is random

---

## Structs

```go
type User struct {
    ID   int
    Name string
}
```

Construction:

```go
u := User{ID: 1, Name: "Jon"}
```

Anonymous:

```go
x := struct{ A int }{A: 1}
```

---

## Methods & Receivers

```go
func (u User) Name() string {}
func (u *User) Rename(n string) {}
```

Rules:

- Value receiver → copy
- Pointer receiver → mutate
- Be consistent

---

## Interfaces

```go
type Reader interface {
    Read([]byte) (int, error)
}
```

Implicit implementation:

```go
type File struct{}
func (File) Read([]byte) (int, error) {}
```

Empty interface:

```go
var x any
```

---

## Generics

```go
func Max[T comparable](a, b T) T {
    if a > b {
        return a
    }
    return b
}
```

Constraints:

```go
type Number interface {
    ~int | ~float64
}
```

- Powerful but intentionally limited
- No specialization or inheritance

---

## Error Handling

```go
v, err := do()
if err != nil {
    return err
}
```

Custom errors:

```go
errors.New("msg")
fmt.Errorf("msg: %w", err)
```

Error wrapping:

```go
errors.Is(err, target)
errors.As(err, &target)
```

---

## `defer`, `panic`, `recover`

### defer

```go
defer f()
```

- Runs at function exit
- LIFO order

---

### panic

```go
panic("fatal")
```

---

### recover

```go
defer func() {
    if r := recover(); r != nil {
    }
}()
```

- Only works inside deferred functions
- Use sparingly

---

## Concurrency

### Goroutines

```go
go doWork()
```

- Lightweight
- Thousands are fine

⚠️ No automatic cancellation or cleanup

---

## Channels

```go
ch := make(chan int)
```

Send / Receive:

```go
ch <- 1
x := <-ch
```

Buffered:

```go
ch := make(chan int, 10)
```

Close:

```go
close(ch)
```

Select:

```go
select {
case v := <-ch:
default:
}
```

---

## Packages & Modules

Init module:

```bash
go mod init example.com/app
```

Import:

```go
import "fmt"
import "example.com/pkg"
```

- One module = many packages
- `go.sum` is checksums, not lockfile

---

## Visibility & Naming

```go
func Public()
func private()
```

- Uppercase = exported
- Lowercase = package-private

---

## Memory & Zero Values

Zero values:

```go
0, false, "", nil
```

Safe defaults:

```go
var s []int // nil but usable
```

Escape analysis decides stack vs heap.

---

## Common Gotchas

- `nil` interfaces ≠ `nil` values
- Loop variable capture in goroutines
- Shadowing with `:=`
- Map iteration order is random
- JSON tags must match exactly
- Slices share backing arrays

---

## Idiomatic Go Rules

- Prefer clarity over cleverness
- Avoid deep abstraction
- Explicit error handling
- Small interfaces
- Composition over inheritance
- One obvious way to do things

---

### TL;DR

Go is:

- **Simple**
- **Explicit**
- **Fast**
- **Predictable**

It rewards discipline and punishes cleverness.