Go vs. Rust: Variable Mutability by Default
Rust variables are immutable by default; Go's are mutable. Rust forces you to opt-in to changeability with `mut` for compile-time safety. Go prioritizes convenience, trusting the developer.
WHY IT EXISTS Languages need rules for how data can change after it's created. This is a fundamental trade-off between safety and flexibility. Rust and Go make opposite default choices based on their core design philosophies: Rust for provable safety, Go for pragmatic simplicity.
THE MENTAL MODEL Think of mutability as a car's transmission. Rust puts you in 'Park' by default; you can't move (change the value) until you explicitly shift to 'Drive' by adding the mut keyword. Go starts you in 'Drive' by default; the variable is ready to be changed at any time.
HOW IT WORKS In Rust, variables are immutable by default. Declaring let x = 5; binds the value 5 to x. Trying to reassign it with x = 6; will cause a compile-time error. To allow changes, you must explicitly declare the variable as mutable: let mut x = 5;. This signals intent to both the compiler and future developers that this value is expected to change.
In Go, variables are mutable by default. Using either x := 5 or var x = 5 creates a variable that can be freely changed later with x = 6. There is no equivalent to Rust's mut keyword because mutability is the standard behavior. Both languages have const for values that are truly constant and known at compile time.
WHEN TO USE IT Rust's immutable-by-default approach is powerful in systems where correctness and preventing data races are critical, such as in concurrent applications or embedded systems. It makes code easier to reason about, as you can be certain a value won't change unless explicitly marked.
Go's mutable-by-default style is suited for rapid development where developer velocity is key. The simpler syntax is convenient for the imperative, straightforward logic common in web services and CLI tools.
WHEN NOT TO USE IT In Rust, avoid sprinkling mut everywhere to silence the compiler. This often indicates you are fighting the ownership model rather than working with it. It may be a sign that your data structures or function signatures could be designed more idiomatically.
In Go, be extremely careful with mutable state that is shared between goroutines. While convenient, this is a primary source of race conditions that Go's compiler won't prevent. You must rely on explicit synchronization with channels or mutexes.
ONE CANONICAL EXAMPLE To make a variable that can be changed from 5 to 6:
In Rust, you must opt-in: let mut x = 5; x = 6; An attempt without mut (let x = 5; x = 6;) fails to compile.
In Go, it's the default: x := 5; x = 6;
Read the original → doc.rust-lang.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.