Side-by-side, interactive cheatsheets for Rust programmers
comparing Rust to other languages. Every example runs live in your browser — no
setup, no installation.
Choose your own path by reordering languages
Go's systems niche, with a garbage collector. A Rust developer reaches for Go when they want fast compiled binaries and goroutines without a borrow checker, lifetimes, or unsafe — trading ownership and zero-cost abstractions for GC simplicity and shorter compile times.
Arc<Mutex<T>> boilerplate; the GC handles memory automaticallyasync/await or a separate runtime; go func() launches a lightweight coroutine instantly(value, error) tuples and if err != nil instead of Result<T, E> and the ? operatorimpl Trait for Type declaration; if the methods match, the type qualifiesnil instead of Option<T> — simpler to write, but the compiler no longer forces you to handle the absent caseWhat Rust developers reach for when the borrow checker isn't the point. Ruby trades ownership, Result, and compile-time guarantees for a garbage-collected world where everything is mutable by default, every value is an object, and blocks let callers control what any method does.
Arc<Mutex<T>>, no move, no borrow errors to reason aboutResult — the happy path is never interrupted by match or ?; errors propagate automatically until something rescues themyield — every method can receive an anonymous block of code; array.map { |x| x * 2 } with no Fn trait bound to declarelet keyword neededString, Integer, or any class at runtime and add methods, without the orphan rule blocking youlet mut; every variable is freely reassignable and mutation is the norm rather than an opt-inThe language Rust was designed to replace. Drop the borrow checker, ownership, and Result: C gives you raw pointers, malloc/free, and a preprocessor — the model that Rust's safety guarantees exist to tame.
let/let mut distinction; immutability requires an explicit const qualifiermalloc allocates and free releases; the compiler never checks: leaks, double-frees, and use-after-free compile silentlyint *pointer is like a raw *mut i32 with no borrow checker to protect youchar arrays — use strcmp instead of ==, snprintf instead of format!, and manage buffer sizes by handvoid* and casting, or preprocessor macros, replace Rust's parameterized typesswitch falls through between cases unless you break — the opposite of Rust's exhaustive, non-fallthrough matchThe Apple-platform sibling with a gentler memory model. Swift keeps Rust's value-type structs, algebraic enums with associated values, and protocols that mirror traits — but replaces the borrow checker with ARC, adds first-class optionals with ? syntax, and brings argument labels that make call sites read like prose.
let is immutable in both, but Swift mutates with var instead of let mutT? syntax and integrate with optional chaining (value?.property) — more concise than Option<T> and .map()switch matches just like Rust's matchfunc move(to point: CGPoint)) make call sites read like natural language — Rust has no equivalentArc<Mutex<T>>TypeScript trades Rust's ownership model and native binary output for a gentler learning curve, a garbage-collected runtime, and the entire npm ecosystem. A Rust developer moving to TypeScript swaps Result for exceptions, Option for null/undefined, and the borrow checker for structural typing on a single-threaded event loop.
impl Trait for Type declaration neededtype Shape = Circle | Rectangle) replace Rust's algebraic enum variants without exhaustiveness enforcement by defaultResult<T, E> — throw/try/catch propagate errors invisibly through the call stack with no ? operatornpm install, no Cargo.tomlasync/await instead of multi-threaded futures — safe from data races by design, but limited to one CPU core per processOptimal software with no hidden control flow. Like C but with memory safety, error handling, and compile-time code execution built in.
The language Rust was designed to replace. C++ shares Rust's zero-overhead philosophy and deterministic memory management — but without the borrow checker, relying on conventions and RAII discipline instead of compile-time enforcement.
Drop, implemented via class destructors that run at end of scopeunique_ptr is Box, shared_ptr is Arc, weak_ptr is Weak; same ownership model, no compiler enforcementstd::variant + std::visit vs Rust enums — the same tagged-union idea, but three times more verbose without pattern matchingstd::expected<T,E> (C++23) mirrors Result<T,E> — error-as-value without exceptions; C++ still has no ? operatorstd::views pipeline syntax closely resembles Rust's iterator chains, but materializing to a collection requires extra boilerplate