→
GOCurriculum
seven modules. Start anywhere — the recommended path is in order, but every theme is browsable. Themes without exercises yet are visible so you can see what's coming.
Progress saves per exercise — re-open any one to continue where you left off. Nothing leaves your browser.
let count: number = 5;
const PI = 3.14;
function double(n: number): number {
return n * 2;
}count := 5
const PI = 3.14
func double(n int) int {
return n * 2
} 1. Foundations
6 themes · 58 exercises
The "you already know this, just spelled differently" module. By the end, you trust that typeover's translation pattern works, and writing trivial Go feels familiar.
TypeScript uses let and const to introduce variables; the type
is inferred or annotated explicitly. Go has two short forms for
the same job:
- name := value — the **short de…
TypeScript has one number type. Go has many: int, int8,
int16, int32, int64, uint* mirrors, float32, and
float64. The big idea: **Go has no implicit numeric conve…
Go strings are immutable byte sequences. There are no template
literals — fmt.Sprintf does the job. A byte is an alias for
uint8; a rune is int32 and represents a Unicode…
if/else looks familiar — no parentheses, braces required. The
one new shape is the short-statement-if: if err := work(); err != nil { ... }.
It scopes a temporary to the…
Functions look familiar — func name(args) returnType { ... } — with
one big new idea: multiple return values. Go functions can return
a tuple, and the convention for "this mi…
2. Collections
3 themes · 32 exercises
Arrays, slices, maps, and the for-range loop. The translation pattern still works but the wrinkles deepen: slices are views, map iteration is unordered, and range gives you index+value.
2.1
Arrays vs slices
Go has fixed-size arrays ([N]T) and dynamically-sized
slices ([]T). You almost always want slices. A slice is a
view over a backing array — three machine words: pointer…
for i, v := range collection is the workhorse. Over a slice you
get (index, value). Over a map you get (key, value). Over a
string you get (byteIndex, rune). Over a channel…
3. Types & methods
4 themes · 36 exercises
The biggest mental-model change so far. TS object literals carry methods; Go structs don't. Methods are functions with a receiver. Pointers become explicit. Nil exists for a specific list of types.
Every type has a zero value — what an uninitialised variable of
that type holds. For numbers: 0. For strings: "". For bools:
false. For pointers, interfaces, maps, slices,…
4. Interfaces & generics
2 themes · 18 exercises
Structural typing in Go's shape — implicit satisfaction with no
implements keyword. Then generics on top: familiar from TS,
mostly syntax to learn.
4.1
Interfaces
interface { Foo() }. A type implements an interface by having the
right methods. There is no implements keyword. Satisfaction is
implicit: if the methods match, the type sa…
5. Errors & packaging
5 themes · 45 exercises
Go's distinctive error convention — the (T, error) return shape,
errors.Is and errors.As for inspection, and the rest of how Go
programs are organised into packages and modules.
Go has no exceptions for ordinary control flow. Errors are values
returned alongside results — (T, error). The caller checks
err != nil and decides. This feels noisy at first;…
Inspecting errors without breaking the wrap chain. errors.Is(err,
target) walks the wrap chain looking for a match against a
sentinel. errors.As(err, &target) walks looking for…
v.(T) asserts that an interface value v is actually of type T.
Panics if wrong. Use the comma-ok form to check first:
if t, ok := v.(T); ok { ... }. For multi-branch checks…
Every file declares a package: package foo. Names starting with
a capital letter are exported; lowercase are package-private.
This rule is mechanical and pervasive; once you…
5.5
Modules & go.mod
A module is a versioned collection of packages — your project's
unit of dependency. go mod init github.com/you/yourthing
produces go.mod. go get adds deps. Module paths look…
6. Concurrency
4 themes · 36 exercises
Native Go territory — no bilingual crutch. Goroutines, channels, select, and the sync primitives. Concurrency as a language-level feature, not a library bolt-on.
6.1
Goroutines
go fn() runs fn concurrently with the caller. That's it. No
promises, no async/await, no event loop — the runtime
multiplexes goroutines over OS threads. Cheap to start (ki…
6.4
Sync primitives
sync.Mutex, sync.RWMutex, sync.WaitGroup, sync.Once. The
classical concurrency toolbox. Go's culture prefers channels
for orchestration and sync for protecting state. Use…
7. Idioms & ecosystem
7 themes · 63 exercises
Graduating to "real Go" — defer, embedding, context, testing, the small-interface idiom, project layout, and the gotchas every Go programmer learns the hard way.
io.Reader { Read(p []byte) (n int, err error) }. One method.
Go interfaces are typically tiny because implicit satisfaction
rewards it — small interfaces are easy to satisfy acci…
7.6
Project layout
cmd/<binary-name>/main.go per binary; internal/... for
packages that should not be importable by other modules. Outside
those two conventions, layout is up to you. The `golang-…
7.7
Common gotchas
The "what bit me in code review" survival kit: - Loop variable capture (Go 1.22+ helped, but you should still know). - Nil interface vs nil concrete (a non-nil pointer inside an…
typeover · curriculum · pass 2
← back to home