Skip to main content

Command Palette

Search for a command to run...

๐Ÿ“ Article 3: Borrowing in Rust โ€” The Cleanest Explanation You Will Ever Read

Updated
โ€ข4 min read
๐Ÿ“ Article 3: Borrowing in Rust โ€” The Cleanest Explanation You Will Ever Read
R

I am a Senior Software Engineer from India.

Rust has a unique superpower called borrowing, which lets you use data without taking ownership.
Itโ€™s the key to writing safe and fast programs without a garbage collector.

But most explanations make it sound complicated.

Hereโ€™s the simplest version โ€” the way I learned it.


โญ Why Borrowing Exists

If a function takes ownership of your value:

fn print_msg(s: String) {
    println!("{}", s);
}

Then this:

let msg = String::from("hello");
print_msg(msg);

println!("{}", msg); // โŒ msg is no longer valid

fails, because the function consumed the string.

But what if the function only needs to read the string, not own it?

Rust has the perfect solution:

๐Ÿ’ก Borrow it instead of moving it.


๐Ÿ” &T โ†’ Immutable Borrow (read-only borrow)

This lets someone temporarily read your value without taking ownership.

Example:

fn print_msg(s: &String) {
    println!("{}", s);
}

fn main() {
    let name = String::from("RAJ");
    print_msg(&name);

    println!("{}", name); // still valid!
}

โœ” Borrowing instead of moving

โœ” Caller retains ownership

โœ” Multiple immutable borrows allowed

This is like:

โ€œYou can read my notebook, but donโ€™t write on it.โ€


๐Ÿ“ Rules of Immutable Borrowing

  • You can have any number of immutable borrows.

  • Data cannot be modified through an immutable borrow.

  • The owner can still use the value after the borrow ends.


๐Ÿ”ฅ &mut T โ†’ Mutable Borrow (borrow with permission to modify)

Sometimes you need to modify the value, but still not take ownership.

Example:

fn shout(msg: &mut String) {
    msg.push_str("!!!");
}

fn main() {
    let mut text = String::from("hello");
    shout(&mut text);

    println!("{}", text); // hello!!!
}

โœ” Borrow with write permission

โœ” Ownership stays with caller

โœ” No ownership move happens

This is like:

โ€œYou can borrow my notebook, but only you can write in it, and only while nobody else is using it.โ€


๐Ÿ“ Rules of Mutable Borrowing

Rust enforces two simple but powerful rules:

1๏ธโƒฃ You can have ONLY ONE mutable borrow at a time.

2๏ธโƒฃ You cannot mix a mutable borrow with any immutable borrows.

This prevents data races, even in single-threaded code.

Example of illegal code:

let mut name = String::from("RAJ");

let r1 = &name;
let r2 = &name;
let r3 = &mut name; // โŒ error

Why error?

Because Rust guarantees:

โ€œIf someone is modifying the data, no one else should be reading it.โ€

It sounds strict, but it prevents entire classes of bugs that happen in other languages.


๐Ÿ” Borrowing Summary

Borrow TypeWhat It MeansAllowed?
&Tread-only borrowmany at the same time
&mut Twrite access borrowonly one at a time
mixed (&T + &mut T)read + write at the same timeโŒ not allowed

Borrowing lets Rust avoid:

  • data races

  • undefined behavior

  • simultaneous reads/writes

  • dangling references

All at compile time.


๐Ÿง  The Big Insight That Made Rust Click

Rust guarantees:

While you have a mutable reference, nobody else can touch the data.

While you have immutable references, nobody can change the data.

This is why Rust can be:

  • memory safe

  • extremely fast

  • concurrency friendly

  • GC-free

Borrowing is not a limitation โ€” itโ€™s a feature that makes safe parallel code trivial.


๐ŸŽฏ Final Takeaway

Borrowing lets functions:

  • use your data

  • modify your data

  • or just read your data

without taking ownership.

Itโ€™s Rustโ€™s elegant solution to memory safety โ€” and once you understand it, Rust becomes much easier.


โญ Coming Next:

If you're following this series, the next article is:

๐Ÿ“ Article 4: The Borrow Checker โ€” Why Rust Stops You and How to Think Like It

This is where we learn:

  • why โ€œmutable + immutableโ€ is forbidden

  • what "value borrowed here after move" really means

  • why Rust errors are actually your friend