Skip to content

Go Cheatsheet — Complete Quick Reference (2026)

DodaTech Updated 2026-06-20 4 min read

In this tutorial, you'll learn about Go Cheatsheet. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

Go is a compiled, statically-typed language designed for simplicity, efficiency, and built-in concurrency — ideal for servers, CLIs, and cloud infrastructure.

Variables & Types

var x int = 42                // explicit
y := "hello"                  // short declaration (type inference)
var z float64                 // zero value (0.0)
var ok bool = true
var s string = "Go"           // zero value ""

// multiple
var a, b int = 1, 2
Type Description
bool true / false
int, int8..int64 Signed integers
uint, uint8..uint64 Unsigned integers
float32, float64 Floating point
string Immutable UTF-8
byte alias for uint8
rune alias for int32 (Unicode code point)
[n]T Array of n T's
[]T Slice of T
map[K]V Map
struct{...} Struct
*T Pointer to T
error Error interface

Control Flow

if x > 0 { } else if x == 0 { } else { }
for i := 0; i < 10; i++ { }       // C-style for
for i < 10 { }                     // while-style
for { }                            // infinite
for idx, val := range slice { }    // iterate
switch x {
case 1:  ...
default: ...
}

Functions

func add(a, b int) int { return a + b }
func swap(x, y string) (string, string) { return y, x }      // multiple returns
func sum(nums ...int) int {                                    // variadic
    total := 0
    for _, n := range nums { total += n }
    return total
}
// closure
func counter() func() int { i := 0; return func() int { i++; return i } }
// named return
func split(sum int) (x, y int) { x = sum / 2; y = sum - x; return }

Structs & Methods

type Person struct {
    Name string
    Age  int
}
p := Person{Name: "Alice", Age: 30}
p := Person{"Alice", 30}             // positional (order matters)

// method (value receiver)
func (p Person) Greet() string { return "Hi, I'm " + p.Name }
// method (pointer receiver — modifies)
func (p *Person) Birthday() { p.Age++ }

Interfaces

type Greeter interface {
    Greet() string
}
// implicit implementation — no "implements" keyword
func greetAll(greeters []Greeter) { for _, g := range greeters { fmt.Println(g.Greet()) } }

// empty interface (any type)
var anything interface{} = 42
var anything any = "hello"           // type alias since Go 1.18

Error Handling

f, err := os.Open("file.txt")
if err != nil {
    return fmt.Errorf("open failed: %w", err)   // wrap error
}
defer f.Close()

// custom error
type MyError struct{ Msg string }
func (e *MyError) Error() string { return e.Msg }

Goroutines & Channels

go func() { fmt.Println("async") }()                     // goroutine

ch := make(chan int)                                      // unbuffered
ch := make(chan int, 10)                                  // buffered
ch <- 42                                                  // send
val := <-ch                                               // receive

select {                                                  // multiplex
case msg1 := <-ch1:  ...
case msg2 := <-ch2:  ...
case <-time.After(1 * time.Second):  ...                  // timeout
default:  ...                                              // non-blocking
}

Concurrency Patterns

// fan-out
jobs := make(chan int, 100)
for w := 0; w < 3; w++ { go worker(jobs) }
func worker(jobs <-chan int) { for j := range jobs { process(j) } }

// sync.WaitGroup
var wg sync.WaitGroup
for i := 0; i < 5; i++ { wg.Add(1); go func(n int) { defer wg.Done(); work(n) }(i) }
wg.Wait()

Testing

// file_test.go
func TestAdd(t *testing.T) {
    got := add(2, 3)
    want := 5
    if got != want { t.Errorf("got %d, want %d", got, want) }
}
// table-driven
func TestAddTable(t *testing.T) {
    tests := []struct{ a, b, want int }{ {2,3,5}, {0,0,0}, {-1,1,0} }
    for _, tt := range tests { if got := add(tt.a, tt.b); got != tt.want { t.Error(...) } }
}
// run: go test ./...

Must-Know Items

  • defer runs when the enclosing function returns (LIFO order)
  • Pointers (*T) enable mutation and avoid copying large structs
  • Channels block by default — buffered channels only block when full/empty
  • select with default creates non-blocking channel operations
  • Error wrapping with %w allows errors.Is() and errors.As() unwrapping
  • Goroutines are lightweight (∼2KB stack) — tens of thousands are fine
  • Use go mod init and go mod tidy for dependency management
  • Exported names start with capital letter (public); lowercase is private to package
What is the difference between a value receiver and a pointer receiver?

A value receiver copies the struct — the method cannot modify the original. A pointer receiver passes a reference — the method can mutate the struct and avoids copying large structs. Use pointer receivers when the method needs to modify the receiver or when the struct is large.

How do goroutines differ from OS threads?

Goroutines are user-space lightweight threads multiplexed onto OS threads by the Go runtime. They start with ∼2KB stacks (vs ∼1MB for threads), have low creation/context-switch cost, and communicate via channels rather than shared memory.

See full Go tutorials for backend development patterns.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro