The Shift in Mindset
When I first picked up Rust, I expected it to be just another language. I was wrong. Rust forced me to confront every lazy habit I had developed over years of writing code in dynamically typed languages.
The borrow checker wasn't an enemy -- it was a teacher. Every compiler error was a lesson in ownership, lifetimes, and what it truly means to write safe code.
What Changed
1. I Started Thinking About Ownership
Before Rust, I never really thought about who "owns" a piece of data. In JavaScript or Python, you create an object and pass it around freely. Garbage collection handles the rest.
Rust makes you explicit. Every value has exactly one owner. When ownership transfers, the old variable is gone. This clarity changed how I design entire systems -- not just Rust code, but architecture in general.
fn take_ownership(s: String) {
println!("{}", s);
} // s is dropped here
fn main() {
let greeting = String::from("Hare Krishna");
take_ownership(greeting);
// greeting is no longer valid here
}
2. Error Handling Became a First-Class Citizen
No more try-catch everywhere. Rust's Result and Option types made me treat errors as data, not exceptions. This pattern has leaked into all my TypeScript code too -- I now use discriminated unions everywhere.
3. Zero-Cost Abstractions
The idea that you can write high-level, expressive code that compiles down to the same assembly as hand-written C is beautiful. It taught me that elegance and performance are not mutually exclusive.
The Bigger Picture
Rust taught me that constraints breed creativity. The stricter the rules, the more carefully you think, and the better the result. This philosophy now applies to everything I build -- from Docker configurations to web applications.
The compiler is not your enemy. It is your most honest code reviewer.