0.3 The Go ↔ Rust ↔ Python phrasebook
Use this table when you know how to say something in Go or Rust and want the Python equivalent. Every row is explained properly later.
| Idea | Go | Rust | Python |
|---|---|---|---|
| Who frees memory | the GC | the owner, at end of scope | reference counting frees most objects immediately; a cycle collector handles cycles (Ch 26) |
| Variables | typed storage | owned values, immutable by default | names bound to objects; assignment never copies (Ch 2) |
| Null | nil |
Option<T> |
None, and X | None in type hints |
| Typing | static | static | dynamic at runtime; optional static hints checked by mypy/pyright (Ch 18) |
| Growable array | []T |
Vec<T> |
list |
| Fixed record | struct |
struct |
@dataclass, NamedTuple, tuple (Ch 15) |
| Map / set | map[K]V |
HashMap, HashSet |
dict (keeps insertion order), set |
| String | string (bytes) |
String / &str (UTF-8) |
str (Unicode code points); bytes for raw bytes (Ch 3) |
| Error | (v, err) |
Result<T, E> + ? |
exceptions: raise / try / except (Ch 7) |
| Cleanup | defer |
Drop |
with blocks (context managers), try/finally (Ch 8) |
| Interfaces | implicit interfaces | traits | duck typing; typing.Protocol for static checks (Ch 17) |
| Generics | type parameters | generics | def f[T](x: T) -> T (3.12+ syntax), checked only by the type checker |
| Iteration | for range |
Iterator trait |
iterator protocol, generators, yield (Ch 13) |
| Lightweight tasks | goroutines | async + Tokio |
asyncio coroutines and tasks (Ch 29) |
| CPU parallelism | goroutines on all cores | threads | processes; threads only on free-threaded builds (Ch 27–28) |
| Channel | chan T |
mpsc |
queue.Queue, asyncio.Queue |
| Mutex | sync.Mutex |
Mutex<T> |
threading.Lock (guards nothing in particular, like Go) |
| Cancellation | context.Context |
drop the future | task.cancel(), asyncio.timeout() |
| Package manager | modules | Cargo | uv + pyproject.toml + uv.lock (Ch 21) |
| Formatter / linter | gofmt, go vet |
rustfmt, clippy |
ruff format, ruff check |
| Tests | go test |
cargo test |
pytest |
| Vulnerability scan | govulncheck |
cargo audit |
pip-audit (Ch 50) |
| Escape hatch to native | cgo |
unsafe, FFI |
C extensions, ctypes, Cython, PyO3 (Rust) (Ch 31) |
| Build artifact | static binary | static binary | source + interpreter, or a wheel; a container in practice (Ch 70) |
The one-sentence version of each language's model:
- Go: values live in typed variables; the GC frees what nothing points to.
- Rust: every value has one owner, and the compiler checks every borrow.
- Python: every value is a heap object with a type and a reference count, and variables are only names stuck onto those objects.