Go Topics
Quick Nav
| Area | Notes |
|---|---|
| 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 course ✅ Completed April 2026
Topics Checklist
Basics
- Hello World —
package main,func main() - Packages — every program is made of packages,
packagedeclaration - 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 -
vardeclaration — package-level and function-level - Short variable declaration —
:=(function scope only) -
varvs:=— 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 + " " + lastNameat 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 -
ifwith short statement —if v := expr; condition {} -
switch— auto-break, cases need not be constants -
switchwith no condition — cleanif-elsechain 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 withslice... -
defer— runs just before enclosing function returns -
defer3 rules — args evaluated immediately; LIFO order; can modify named return values
Pointers
-
*T— pointer type; zero valuenil -
&— address-of operator -
*— dereference operator - Pointers to structs —
p.Xshorthand 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
implementskeyword - 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) vsv := 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
-
errorinterface —Error() stringmethod -
fmt.Errorf("context: %w", err)— wrapping errors with context -
errors.New("message")— simple sentinel error creation - Custom error types — struct implementing
errorinterface -
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 insidedefer; catches panic - Use
log.Fatalfor controlled exits, notpanic
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 labelfor nested loops
Slices
- Slice basics —
[]T, dynamic size, backed by array - Slice of array —
arr[low:high], shared backing array -
lenandcap -
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
-
packagedeclaration —mainvs 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 -
rangeover channel — reads until closed - Channel direction —
chan<- Tsend-only,<-chan Treceive-only -
select— multiplex multiple channels, picks ready one at random -
selectwithdefault— non-blocking channel operation -
selectwith timeout —time.After - Done channel — cancellation signal via
close(done) -
sync.WaitGroup—Add,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.Mutex—Lock/Unlock, alwaysdefer Unlock -
sync.RWMutex—RLock/RUnlockfor 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.Stringerfor 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
-
contextpackage — cancellation, deadlines, timeouts
Go vs Python Quick Reference
| Concept | Python | Go |
|---|---|---|
| Typing | Dynamic | Static |
| Concurrency | GIL limited | Goroutines + channels |
| Error handling | try/except | if err != nil |
| OOP | Classes | Structs + interfaces |
| Package manager | pip / poetry | go mod |
| Run | python file.py | go run file.go |
| Build | N/A | go build |
| Format | Black / ruff | go fmt (built-in) |
| Null | None | nil |
| Any type | Any | interface{} / any |
| Named returns | No | Yes |
| Multiple returns | Tuple unpacking | Native |
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
| Gotcha | Detail |
|---|---|
:= outside function | Not allowed — use var at package level |
| Unused imports | Compile error |
| Unused variables | Compile error |
| No implicit type conversion | float64(x) not just x |
defer LIFO | Last defer runs first |
| Naked return | Only in short functions — hurts readability in long ones |
panic vs error | panic for unrecoverable bugs only; return error for expected failures |