A FRIENDLY COURSE

Learn Go,
the Pythonista's way

Eight visual lessons that take you from print("hello") to writing real Go services. Built for Python developers - lots of side-by-side code, diagrams for every tricky concept, and a 5-year-old explanation when you need one.

Why Go, coming from Python?

You already write Python. So why learn Go at all? Three reasons that matter in practice:

~50x slower
Python CPU work
~2x of C
Go CPU work
8 MB
Python thread
2 KB
Go goroutine
venv + deps
Python deploy
1 binary
Go deploy
If you care about Python gives you Go gives you
SpeedInterpreter overhead. Fast to write, slow to run.Compiled native binary. Predictable performance.
ConcurrencyThe GIL serializes threads. asyncio is powerful but viral and awkward.Goroutines are dirt cheap. One go f() spawns concurrent work. Channels for safe communication.
Deployment"Works on my machine" with the right venv, Python version, and 47 wheels.One static binary. Copy it to a server and run.
TypesOptional type hints, checked by an external tool (mypy) you might forget to run.Types are mandatory and checked by the compiler.
Ecosystem fitData science, ML, scripting, web (Django/Flask).Cloud-native: Kubernetes, Docker, Prometheus, Terraform, etcd are all in Go.

Speed at a glance

Fibonacci(35), single-threaded Python 3.5 s Go 0.04 s 0s ~4s Go is ~85x faster on this benchmark (illustrative)
Approximate. Real ratios vary by workload, but the order-of-magnitude gap is real for CPU-bound code.

Deployment at a glance

Python: ship many things app.py your code requirements .txt venv/ 47 packages python3.11 interpreter .env config → all must match prod Each piece can drift. One mismatch and "works on my machine" wins. Go: ship one thing myapp 8 MB static binary scp + ./myapp it runs. done. → no runtime needed Cross-compile for any OS/arch from your laptop. GOOS=linux go build
"Pip install requirements" vs "scp the binary." This single difference is why Kubernetes, Docker, and most cloud tooling pick Go.
The honest take: Go is not "better than" Python. It's a different tool. Python is faster to write and explore with. Go is faster to run, easier to deploy, and the language of cloud infrastructure. For backend services, CLIs, or anything Kubernetes-shaped, Go pays off quickly.

The learning path

Eight bite-sized lessons. Each builds on the previous, but each also stands alone if you need a refresher later.

1. Hello, Go first program 2. Types & vars static typing 3. Control flow if / for / switch 4. Functions multi-return, closures 5. Collections arrays, slices, maps 6. Structs & pointers data + methods 7. Error handling no exceptions! 8. Packages go.mod, imports You can build! APIs, CLIs, tools
Blue = language essentials. Green = data structures. Yellow = professional habits. Finish all 8, you can write real Go.
1

Hello, Go

Your first Go program. How package main works. go run vs go build. Why Go compiles instead of interprets.

2

Types & variables

Static typing without the pain. var, const, the := shorthand. Zero values (the death of None).

3

Control flow

Go has only one loop keyword: for. Plus if with init, smart switch, and defer (a superpower).

4

Functions

Multiple return values (no more tuples!), named returns, variadic args, closures. Functions are first-class.

5

Collections

Arrays vs slices vs maps. How slices secretly share memory (the famous gotcha). Iterating with range.

6

Structs & pointers

Go's "classes that aren't classes." Methods. Pointer vs value receivers. Embedding instead of inheritance.

7

Error handling

No try/except. Errors are values you return and check. panic/recover for the rare emergency.

8

Packages & modules

go.mod, imports, why Capitalized names are public, and how to use the standard library.

How to read these lessons

Each lesson has the same shape so you always know what to expect:

SectionWhat it gives you
The 5-year-old versionA plain-English analogy in an orange box. Click to expand; skip if you don't need it.
Python you know ↔ GoSide-by-side code. Blue = Python, teal = Go. Read both. Spot the differences.
What's different and whyShort prose explaining the mental shift. This is where the real learning happens.
DiagramVisual model for concepts text struggles with (slice internals, defer stacks, etc).
Real exampleSomething from a real codebase: an HTTP handler, a CLI flag, a k8s reconciler snippet.
GotchasMistakes Python devs make in Go. Red boxes. Read them twice.
GlossaryTerms used in the lesson, anchored to the page.
Try this: Most code samples have a "Copy" button (hover the code). Paste into go.dev/play and hit Run. Change something. See what breaks. Five minutes of experimentation beats an hour of reading.

Before you start: a 60-second setup

You can do everything in this course on go.dev/play without installing anything. To write real programs, install Go locally:

macOS (Homebrew)
# install
brew install go

# verify
go version
# go version go1.23 darwin/arm64
Linux / Windows
# Linux: download from go.dev/dl, extract to /usr/local
tar -C /usr/local -xzf go1.23.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin

# Windows: download the MSI from go.dev/dl, double-click

Editor: VS Code + the official Go extension. Autocomplete, jump-to-definition, format-on-save, inline errors. Or use whatever you already use - gopls (the Go language server) plugs into most editors.

Start with Lesson 1: Hello, Go →

Quick mental-model cheat sheet

Save this. If you're confused mid-lesson, come back here.

In Python you say…In Go you say…Notes
x = 5x := 5 or var x int = 5Go infers the type. := declares + assigns.
def add(a, b): return a + bfunc add(a, b int) int { return a + b }Types after the name. Return type after the signature.
my_list = [1, 2, 3]nums := []int{1, 2, 3}A slice. Looks like a list, behaves slightly differently (lesson 5).
my_dict = {"a": 1}m := map[string]int{"a": 1}Maps in Go are typed: key type and value type.
class Dog: ...type Dog struct { ... }No classes. Just structs + methods. Composition over inheritance.
try: ... except: ...x, err := f(); if err != nil { ... }Errors are return values, not exceptions. Check every one.
NonenilSame idea. But primitives like int can't be nil; they default to 0.
print("hi")fmt.Println("hi")Functions live in packages. fmt is the formatted-I/O package.
import requestsimport "net/http"Import paths are strings. Standard library covers HTTP, JSON, crypto, etc.
async def f(): ...go f()Run any function concurrently with go. (Concurrency is a later course.)

Course glossary

TermMeaning
go (the tool)The Go command-line tool. Runs, builds, tests, formats, manages dependencies. One CLI for everything.
goplsThe Go language server. Powers IDE features (autocomplete, jump-to-definition, refactor).
go.modThe "requirements.txt + setup.py" of Go. Declares module name and dependencies.
ModuleA versioned bundle of related Go packages. Like a Python distribution package.
PackageA directory of .go files sharing a namespace. Like a Python module.
GoroutineA lightweight concurrent function. Like a thread but ~2 KB to spawn. Managed by the Go runtime.
ChannelA typed pipe for safely passing values between goroutines. The Go answer to queue.Queue + locks.
Zero valueThe default value of a freshly declared variable. 0 for numbers, "" for strings, nil for pointers/maps/slices.
ReceiverThe "self" of a Go method, but spelled before the method name: func (d *Dog) Bark().
InterfaceA set of methods. Any type with those methods implicitly satisfies the interface (no implements keyword).