Go, by example
Go by example - concurrency, simplicity, and production idioms.
86 lessons ยท Updated 2026-10-09
- 01Hello, WorldThe smallest runnable Go program - package main, the main function, and fmt.Println.
- 02Packages and ModulesPackages group Go source files; modules record import paths, the minimum Go version, and external dependencies.
- 03ValuesGo's built-in scalar types - bool, integer variants, float32/float64, byte, rune, and string.
- 04Variablesvar declarations, short variable declaration :=, zero values, and multiple assignment.
- 05Constantsconst, iota, typed vs untyped constants, and constant expressions evaluated at compile time.
- 06ForGo's single loop statement supports counter loops, condition loops, infinite loops, and range iteration.
- 07If/ElseConditional branching with if, else if, and else - including the idiomatic init-statement form used for error checks.
- 08SwitchSwitch statements match values, conditions, and interface values without implicit fall-through.
- 09ArraysFixed-length typed arrays - declaration, zero initialisation, array literals, comparison, and multi-dimensional arrays.
- 10SlicesDynamic sequences built on arrays, including length, capacity, append, and shared backing storage.
- 11MapsKey-value stores with make, literals, get/set/delete, the comma-ok idiom, and range iteration.
- 12FunctionsDeclaring functions with typed parameters and results, and passing functions as values.
- 13ClosuresFunctions that capture variables from their surrounding scope, including closures used by goroutines.
- 14PointersTaking a value's address, reading or changing it through a pointer, and handling nil.
- 15StructsDefining a struct, naming its fields, creating values, and understanding zero values.
- 16MethodsDeclaring methods with value and pointer receivers, and seeing how each receiver affects mutation.
- 17Multiple Return ValuesGo functions can return more than one value - the canonical pattern is returning a result alongside an error.
- 18Variadic FunctionsA variadic function accepts a variable number of arguments via the ...T parameter - the basis of fmt.Println, append, and ergonomic APIs.
- 19RecursionFunctions that call themselves - Go supports recursion with automatic goroutine stack growth, though deep trees are better handled with an explicit stack.
- 20Range over Built-in TypesThe range keyword iterates over slices, maps, strings, channels, and integers - each with different iteration semantics worth knowing.
- 21Strings and RunesGo strings are immutable byte sequences and may contain arbitrary bytes; a rune represents a Unicode code point.
- 22InterfacesGo interfaces are satisfied implicitly - any type that implements the required methods satisfies the interface, no declaration needed.
- 23EnumsGo has no built-in enum type - idiomatic enums use typed integer constants with iota to generate sequential values.
- 24Struct EmbeddingGo has no class inheritance; struct embedding promotes fields and methods while composing types.
- 25GenericsGo 1.18 added generics - type parameters let you write functions and types that work across multiple types without losing type safety.
- 26Range over IteratorsSince Go 1.23, range can iterate over functions that yield values; iterators must stop when yield returns false.
- 27Errorserrors.New, fmt.Errorf with %w, errors.Is, errors.As, and sentinel errors - Go errors are values.
- 28Custom ErrorsImplementing the error interface with a struct to carry structured context callers can extract.
- 29GoroutinesLaunch concurrent function calls with the go keyword and wait for them to finish safely.
- 30ChannelsSend typed values between goroutines and synchronize their work with channels.
- 31Channel BufferingUse a fixed-size channel queue to let producers and consumers work at different speeds.
- 32Channel SynchronizationUse channels as done signals to wait for goroutines to finish before continuing.
- 33Channel DirectionsRestrict channels to send-only or receive-only in function signatures to document and enforce data flow.
- 34SelectChoose a ready channel operation from several cases, or wait until one can proceed.
- 35TimeoutsBound how long you wait for a channel operation using time.After or context.WithTimeout inside a select.
- 36Non-Blocking Channel OperationsUse select with a default case to attempt a channel send or receive without blocking.
- 37Closing ChannelsClose a channel to broadcast completion; only senders should close.
- 38Range over ChannelsIterate over channel values until the channel is closed using a for-range loop.
- 39TimersSchedule a one-shot event with time.NewTimer and cancel it early with Stop.
- 40TickersFire repeatedly at a fixed interval with time.NewTicker, and stop it when its recurring work is no longer needed.
- 41Worker PoolsFan out work across N goroutines reading from a shared jobs channel to bound concurrency.
- 42WaitGroupsUse sync.WaitGroup to wait for a collection of goroutines to finish.
- 43Rate LimitingControl the rate of operations using tickers and the golang.org/x/time/rate token bucket.
- 44Atomic CountersUse typed sync/atomic operations for independent counter updates and reads across goroutines.
- 45MutexesUse sync.Mutex to safely share state across goroutines when atomic operations are not enough.
- 46Stateful GoroutinesConfine mutable state to a single goroutine and expose it through channels to avoid data races by design.
- 47SortingSort slices of ordered values in place; choose stable or custom sorting when comparison rules require it.
- 48Sorting by FunctionsCustom sorting with slices.SortFunc, multi-key sorting with cmp.Compare, and stable vs unstable sort.
- 49PanicUse panic for unrecoverable program errors and return errors for expected failures.
- 50DeferSchedule cleanup and other calls to run when the current function returns.
- 51RecoverRecover from panics in deferred functions, re-panicking, and converting panics to errors at package boundaries.
- 52String FunctionsSearch, split, trim, replace, and build strings efficiently with the strings package.
- 53String FormattingFormat values with fmt verbs and choose between printing, writing, or returning a string.
- 54Text TemplatesRender data with Go templates and use HTML escaping for browser output.
- 55Regular ExpressionsCompile a regular expression once, find all matching numbers, and replace the matches.
- 56JSONEncode and decode JSON structs with field tags and omitempty; use Decoder for stream input and strict field validation.
- 57XMLUse encoding/xml tags for elements and attributes, marshal or unmarshal values, and use Decoder for large inputs.
- 58Timetime.Time, time.Now, Duration arithmetic, time.Since and time.Until, Add and Sub, and comparisons with Before, After, and Equal.
- 59EpochUnix epoch seconds and nanoseconds, converting back with time.Unix, and best practices for storing timestamps in databases.
- 60Time Formatting / ParsingFormat and parse times with reference-time layouts, standard layouts such as RFC3339, and ParseInLocation.
- 61Random Numbersmath/rand/v2 for general-purpose randomness, global functions vs local Source, and crypto/rand for cryptographically secure randomness.
- 62Number Parsingstrconv.Atoi and ParseInt for integers, ParseFloat for floats, FormatInt and Itoa for the reverse, and error handling on invalid input.
- 63URL ParsingParse URLs into components and safely encode query values with net/url.
- 64SHA256 Hashescrypto/sha256 for one-shot and streaming SHA-256 hashing, hex encoding the digest, and when not to use SHA256 for passwords.
- 65Base64 EncodingChoose URL-safe Base64 encoding, handle decode errors, and stream large payloads with NewEncoder.
- 66Reading FilesRead manageable files with os.ReadFile or scan lines from os.Open; check scanner errors and account for its token limit.
- 67Writing FilesWrite small files with os.WriteFile; stream with bufio.Writer, append with os.OpenFile, and call Sync when durability is required.
- 68Line FiltersBuild a line filter that transforms stdin and writes results to stdout, with scanner limits and error handling.
- 69File PathsBuild, split, and clean filesystem paths with filepath; use WalkDir for recursive traversal and validate untrusted paths separately.
- 70DirectoriesCreate nested directories, list entries, remove directory trees, and traverse recursively with error handling.
- 71Temporary Files and Directoriesos.CreateTemp and os.MkdirTemp for creating temporary files and directories, deferred cleanup, and t.TempDir in tests.
- 72Embed DirectiveUse //go:embed to bundle a file into a string, byte slice, or embed.FS at build time.
- 73Testing and BenchmarkingGo's built-in testing package provides TestXxx functions, table-driven tests, BenchmarkXxx functions, and the testdata directory convention without external frameworks.
- 74Command-Line Argumentsos.Args provides raw access to command-line arguments as a string slice, with os.Args[0] holding the program name as invoked and os.Args[1:] holding the user-supplied arguments.
- 75Command-Line FlagsParse named flags and positional arguments with flag; typed flag values are pointers, and parsing stops at the first positional argument.
- 76Command-Line Subcommandsflag.NewFlagSet creates a per-subcommand flag set, enabling tools with subcommands like "git commit" or "docker run" where each subcommand has its own flags.
- 77Environment Variablesos.Getenv reads env vars; os.LookupEnv distinguishes "not set" from "set to empty string" - critical for required config validation at startup.
- 78LoggingUse log/slog handlers and structured fields; configure JSON or text output, levels, and sensitive-data handling.
- 79HTTP ClientSet a client timeout or request context deadline to bound HTTP calls, and reuse clients to share connections.
- 80HTTP ServerConfigure http.Server timeouts for slow reads and idle connections, and account for WriteTimeout on streaming responses.
- 81TCP ServerAccept TCP connections, handle clients concurrently, and set deadlines to bound stalled reads.
- 82ContextUsing context cancellation and deadlines to stop work across a call chain.
- 83Spawning ProcessesUse os/exec with separate arguments to start processes without a shell; add context cancellation and validate target arguments.
- 84Exec'ing ProcessesReplace the current process on Unix with syscall.Exec; a successful handoff skips deferred functions.
- 85Signalssignal.NotifyContext ties a context to SIGINT/SIGTERM - cancel it to propagate graceful shutdown to every goroutine that respects context cancellation.
- 86ExitKeep cleanup in a run function; report errors from main and exit nonzero after cleanup completes.
Enjoyed this? Get more software craft delivered to your inbox.