© Anton Dolganin 2025
This article doesn’t aim to teach you Rust or unveil some hidden feature. It’s more like an experiment — a way to show a kid what Rust looks like on the inside (Rust, not the kid), rather than how to write idiomatic Rust code.
In other words, devs are used to judging a language by how well it fits into their mental model of “how code should be written.” And when it doesn’t? That’s when the frustration kicks in.
Here, I tried flipping the perspective — think “picture book”: how the language lives and breathes, not how we’ve learned to structure it.
⚠️ Disclaimer: This article isn’t about Copy types like
i32
,f64
,bool
,char
, or&T.
We're diving into move types — like String — where values are actually moved around.
Alright, let’s roll.
We’ll start with a core idea in Rust: a value (a memory cell) can only have one owner at a time. Let’s introduce a bit of “storybook” notation:
let
= “let it be”
=
= “takes ownership”
mut
= “money”, yep, just a money ;)
let
Let’s let a
own a House:
let a = String::from("House");
Now let’s let b
own that same House. According to the rules, the previous owner has to move out — no exceptions:
let b = a;
At this point:
println!("a = {}", a);
Boom — error.
Why? Because a
no longer has the right to do anything with the value (its former House). Ownership was transferred, and Rust enforces that hard.
mut
But wait — there’s more. Just owning a House doesn’t mean you can start remodeling it. Think of it like renting someone else's place — ownership without modification rights.
So this will trigger an error:
b.push_str(" with Pool"); // 🔴 error
If you want to make changes, you have to buy the House with some extra money mut
.
let mut c = b;
c.push_str(" with pool");
println!("{}", c); // House with pool
Now c
has the keys and the renovation permit.
&
We can share access to the House — say, by letting a buddy crash for a while. You hand them a copy of the keys using &
:
let d = &c;
println!("{}", c);
println!("{}", d);
But there’s a catch. According to the social contract, if guests are inside, no renovations allowed. The following code will throw an error:
let d = &c;
c.push_str(" with sandbox");// can't renovate while guests are over
println!("{}", c);
println!("{}", d);// guest is here
You have to wait until the guests leave:
let d = &c;
println!("{}", d);// guest leaves
c.push_str(" with sandbox");
Still confused? There’s a full “guest etiquette” section at the end of the article.
& mut
Now let’s say your buddy wants to add a hot tub. Since that’s a modification to the House, you ask him to chip in — and in return, you give him the real keys with change privileges: &mut
.
let e = &mut c;
e.push_str(" and with hot tub");
println!("{}", e);
Just remember: same rule applies — if someone else is holding the keys, you can’t do any remodeling. In fact, while your buddy is chilling in the hot tub, you can’t even enter the house:
let e = &mut c;
e.push_str(" and with hot tub");
println!("{}", c);
println!("{}", e);// buddy’s in the hot tub
You have to wait for them to finish:
let e = &mut c;
e.push_str(" and with hot tub");
println!("{}", e);// buddy’s done
println!("{}", c);
This only applies when you gave out “paid” access (&mut
) — not when you just let someone couch-surf with &.
mut &mut
Now we rent out the House again — to another buddy, this time with full mod rights. But this buddy also has their own extra money — mut
.
let mut f = &mut c;
f.push_str(" and with garden");
Things are going well, and we decide to buy a second place: Apartment.
let mut c2 = String::from("Apartment");
Our buddy’s not slacking either — “Let me try out the Apartment too,” he says, waving his mut
wallet. So he moves out of the House, into the Apartment, and starts upgrading that too:
f = &mut c2;
f.push_str(" with elevator");
Same core idea: ownership with editing rights = &mut
. And declaring let mut f
means this buddy isn’t tied to just one location — he can move between places and make changes. Because money mut, yep
After he’s gone, we end up with both properties modified:
println!("c: {}", c);
println!("c2: {}", c2);
//c: House with pool and with sandbox and with hot tub and with garden
//c2: Apartment with elevator
Note: When I say “the buddy left,” I mean it literally — he’s gone, out of scope. Rust tracks that. If a variable is no longer used later in the code, Rust considers it dead — like you called delete
on it.
That’s why things can seem weird: while the guest is “around,” you’re blocked from doing stuff, but it’s not always clear they’ve “left.” Rust figures it out by analyzing whether the variable is used again — if not, it’s safe to proceed.
Functions
With a few rare exceptions, the same rules apply to functions too. I won’t overload this post with function examples — maybe next time :)
© Anton Dolganin 2025