Back to Notes

Go Topics

Quick Nav

AreaNotes
Basics[[Basics]]
Variables & Types[[Variables & Types]]
Control Flow[[Control Flow]]
Functions[[Functions]]
Pointers[[Pointers]]
Structs[[Structs]]
Interfaces[[Interfaces]]
Error Handling[[Errors]]
Loops[[Loops]]
Slices[[Slices]]
Maps[[Maps]]
Packages & Modules[[Packages & Modules]]
Channels & Goroutines[[Channels]]
Mutexes[[Mutexes]]
Generics[[Generics]]
Enums[[Enums]]
Go Proverbs[[Go Proverbs]]
HTTP Clients[[HTTP Clients]]
Quiz & Challenges[[Go Quiz & Challenges]]

Learning path: Boot.dev Go courseCompleted April 2026


Topics Checklist

Basics

  • Hello World — package main, func main()
  • Packages — every program is made of packages, package declaration
  • Imports — factored import () statement
  • Exported names — capital letter = exported, lowercase = unexported
  • Comments — // single-line, /* */ multi-line

Types & Variables

  • Basic types — bool, string, int, uint, byte, rune, float32/64, complex64/128
  • Zero values — 0 / false / "" / nil
  • Type conversion — T(v) explicit only, no implicit conversion
  • Type inference — := infers type from RHS
  • var declaration — package-level and function-level
  • Short variable declaration — := (function scope only)
  • var vs := — when to use which
  • Variable shadowing — inner := hides outer variable
  • Constants — const, compile-time only, character/string/bool/numeric
  • Numeric constants — high-precision untyped, takes type from context
  • Computed constants — firstName + " " + lastName at compile time
  • iota — auto-incrementing constant enumeration

String Formatting

  • fmt.Printf — prints to stdout
  • fmt.Sprintf — returns formatted string
  • Verbs — %v (default), %s (string), %d (int), %f / %.2f (float), %T (type), %q (quoted string)

Control Flow

  • if / else if / else — no parentheses, braces required
  • if with short statement — if v := expr; condition {}
  • switch — auto-break, cases need not be constants
  • switch with no condition — clean if-else chain alternative
  • fallthrough — explicit fall to next case
  • for — only loop construct; C-style, while-style (for cond {}), infinite (for {})
  • range — iterate over slice/map/string/channel; skip with _

Functions

  • Multiple return values — func swap(x, y string) (string, string)
  • Named return values — naked return
  • Blank identifier _ — ignore unwanted return values
  • Anonymous functions — func(a int) int { return a + a }
  • Functions as values — first-class, assignable to variables, dispatch tables
  • Closures — function that captures variables from outer scope
  • Variadic functions — func sum(nums ...int), spread with slice...
  • defer — runs just before enclosing function returns
  • defer 3 rules — args evaluated immediately; LIFO order; can modify named return values

Pointers

  • *T — pointer type; zero value nil
  • & — address-of operator
  • * — dereference operator
  • Pointers to structs — p.X shorthand for (*p).X
  • Value vs pointer receivers — when to mutate vs read-only
  • new(T) — allocate zero value, returns *T
  • Stack vs heap — escape analysis, safe to return pointer from function
  • Nil pointer dereference — runtime panic, always check nil

Structs

  • Struct definition — type Name struct { Field Type }
  • Field access via .
  • Nested structs
  • Anonymous structs — inline definition + instantiation
  • Embedded structs — field promotion (data-only inheritance)
  • Struct methods — value receiver vs pointer receiver
  • Struct tags — json:"name,omitempty", json:"-"
  • Memory layout — contiguous block; field ordering affects padding
  • Empty struct struct{} — zero bytes, used as signal value

Interfaces

  • Interface definition — collection of method signatures
  • Implicit implementation — no implements keyword
  • Multiple interfaces — a type can satisfy many interfaces
  • Interface values — (type, value) pair; nil interface vs interface holding nil
  • Empty interface interface{} / any — satisfied by all types
  • Named interface parameters — improves readability
  • Interface composition — embedding interfaces
  • Type assertion — v, ok := x.(T) (safe) vs v := x.(T) (panics)
  • Type switch — switch v := x.(type) { case int: ... }
  • Key stdlib interfaces — fmt.Stringer, error, io.Reader, io.Writer, sort.Interface
  • Best practices — accept interfaces, return concrete types; keep interfaces small

Errors

  • error interface — Error() string method
  • fmt.Errorf("context: %w", err) — wrapping errors with context
  • errors.New("message") — simple sentinel error creation
  • Custom error types — struct implementing error interface
  • errors.Is — check if error chain contains target
  • errors.As — extract typed error from chain
  • Convention — return error as last value; return zero values on error
  • Sentinel errors — package-level var ErrXxx = errors.New(...)
  • panic — stops normal execution, unwinds stack (use for bugs only)
  • recover — must be inside defer; catches panic
  • Use log.Fatal for controlled exits, not panic

Loops

  • for — only loop construct; C-style, while-style (for cond {}), infinite (for {})
  • range — iterate over slice/map/string/channel; skip with _
  • continue / break — skip iteration or exit loop
  • Labeled loops — break label / continue label for nested loops

Slices

  • Slice basics — []T, dynamic size, backed by array
  • Slice of array — arr[low:high], shared backing array
  • len and cap
  • make([]T, len, cap) — pre-allocated slice
  • append — returns new slice, auto-reallocates
  • copy(dst, src) — independent copy
  • Nil slice — safe to range and append
  • Remove element — append(s[:i], s[i+1:]...)
  • 2D slices

Maps

  • map[K]V — unordered hash map
  • make(map[K]V) — initialise before writing
  • Insert, read, update, delete
  • Comma-ok idiom — v, ok := m[k]
  • Zero value for missing keys
  • Iterating — for k, v := range m
  • Map of slices
  • Set pattern — map[K]struct{}

Packages & Modules

  • package declaration — main vs library packages
  • Exported vs unexported names — capital letter = exported
  • import — factored imports, aliases, blank imports
  • Modules — go.mod, go.sum, go mod init, go mod tidy
  • Standard library overview
  • init() function
  • Project structure and internal packages

Channels & Goroutines

  • Goroutines — go func(), lightweight threads, main exits kills all
  • Unbuffered channels — synchronous handshake, both sides must be ready
  • Buffered channels — make(chan T, n), blocks only when full/empty
  • close(ch) — sender signals no more values; receive from closed returns zero + ok=false
  • range over channel — reads until closed
  • Channel direction — chan<- T send-only, <-chan T receive-only
  • select — multiplex multiple channels, picks ready one at random
  • select with default — non-blocking channel operation
  • select with timeout — time.After
  • Done channel — cancellation signal via close(done)
  • sync.WaitGroupAdd, Done, Wait
  • Worker pool pattern — fixed goroutines consuming from jobs channel
  • Channel axioms — nil channel blocks, closed channel panics on send, returns zero on receive

Mutexes

  • sync.MutexLock / Unlock, always defer Unlock
  • sync.RWMutexRLock / RUnlock for concurrent reads
  • sync.Once — run initialisation exactly once
  • Embed mutex in the struct it protects; always use pointer receiver

Generics

  • Type parameters — func F[T any](x T)
  • Built-in constraints — any, comparable
  • Type-set interfaces — union types int | float64, only valid as constraints
  • ~T — underlying type constraint
  • Generic structs and interfaces
  • Multiple type parameters

Enums

  • iota — auto-incrementing typed constants
  • Skipping zero value with _
  • Bitmask flags with 1 << iota
  • String() method / fmt.Stringer for readable output
  • Exhaustive switch + validation at boundaries

HTTP Clients in Go (Boot.dev — In Progress)

  • Why HTTP — request/response model, status codes
  • JSON — encoding/json, Marshal / Unmarshal, struct tags
  • DNS — hostname resolution, net.LookupHost
  • URIs — url.Parse, url.Values, query encoding
  • Headers — req.Header.Set, Authorization schemes
  • Methods — GET, POST, PUT, DELETE
  • Paths — path params, query params
  • HTTPS — TLS handshake, InsecureSkipVerify
  • Errors — transport errors vs HTTP status errors, timeouts
  • cURL — curl ↔ Go equivalents

Beyond Boot.dev

  • context package — cancellation, deadlines, timeouts

Go vs Python Quick Reference

ConceptPythonGo
TypingDynamicStatic
ConcurrencyGIL limitedGoroutines + channels
Error handlingtry/exceptif err != nil
OOPClassesStructs + interfaces
Package managerpip / poetrygo mod
Runpython file.pygo run file.go
BuildN/Ago build
FormatBlack / ruffgo fmt (built-in)
NullNonenil
Any typeAnyinterface{} / any
Named returnsNoYes
Multiple returnsTuple unpackingNative

Key Commands

go mod init <module-path>   # initialise module
go mod tidy                 # sync go.sum (add missing, remove unused)
go run main.go              # run without compiling
go build                    # compile to binary
go test ./...               # run all tests
go fmt ./...                # format all files
go vet ./...                # static analysis
go doc <pkg>                # view package documentation

Common Gotchas

GotchaDetail
:= outside functionNot allowed — use var at package level
Unused importsCompile error
Unused variablesCompile error
No implicit type conversionfloat64(x) not just x
defer LIFOLast defer runs first
Naked returnOnly in short functions — hurts readability in long ones
panic vs errorpanic for unrecoverable bugs only; return error for expected failures