01
Language Basics
Tying the language's design goals to readability and compile speed, running the first program with module initialization, short declaration alongside sequential constants, the distinction between integer and floating-point types, the defined behavior of every variable left without an initial value, control flow and loop forms gathering into a single keyword, and what a multiple return value and a variadic argument correspond to in an empty call.
- 01 Go's Design Goals Four things the Go compiler rejects — an unused variable, an unused import, an unwritten return value, an implicit type conversion — are run from inside the program by calling a compiler; all four stop compilation, and rejecting the implicit conversion grows the source doing the same work from 15 characters to 22.
- 02 Environment Setup and the First Program Three things are mandatory for a Go source to compile: a package declaration, an entry point (func main), and a module file; when one of the three is missing, compilation is rejected even if the rest of the source has not changed at all — the module file never sits inside the source itself.
- 03 Variables and Constants Short declaration decides a variable's type without ever writing it into the source; only two of a six-constant iota sequence have a value written in the source — the other four come from repeating the previous expression — and the same short-declaration line is rejected at package level while it is accepted inside a function.
- 04 Basic Types Four unwritten cases are run through the same frame: an untyped constant's default type turns out to be int, a sum that overflows an int8 wraps to -128, two float64 values added at runtime do not come out equal to 0.3, and a character literal's type is actually int32 — rune is only an alias. Limiting measurement: the implicit-conversion rejection does not hold for constants.
- 05 Zero Values Fifteen unwritten cases are run through a single frame: eight find a defined counterpart from the language, four are rejected by the compiler, three are left open to runtime. Limiting measurement: nil can be appended to a slice but cannot be written to a nil map — both are the same kind of zero value.
- 06 Control Flow Five forms are measured with the same question — unconditional for, single-condition for, expressionless switch, an early return without an else, a switch branch that does not fall through on its own — and all five fill the unwritten part with a defined counterpart. Limiting measurement: an unwritten break is not needed, but code that wants to fall through has to write an extra word (fallthrough).
- 07 Functions A named return value left completely untouched carries its type's zero value; a function never writing a return value at all is rejected at compile time, but a caller ignoring what comes back without ever catching it says nothing at all — since error is itself just a return value in Go, this open behavior is the course's most important example. Limiting measurement: once a return value is captured into a variable and left unused, this openness closes and the unused-variable rejection takes over.
- 08 Variadic Functions A variadic parameter given no argument at all becomes a nil slice, arguments written one by one produce a fresh slice, and opening an existing slice with ... shares the same backing array without copying it — a change the callee makes is visible to the caller. Limiting measurement: a nil slice and an empty slice are the same length but diverge on == nil, and this difference becomes visible in their JSON counterpart.