Mutable References
Shared references (&T) are read-only. To modify borrowed data, you need a mutable reference (&mut T):
fn add_greeting(text: &mut String) {
text.push_str(", hello!");
}
let mut message = String::from("World");
add_greeting(&mut message);
assert_eq!(message, "World, hello!");
Python comparison
In Python, you can modify objects passed to functions because everything is a reference:
def add_item(items, item):
items.append(item)
my_list = [1, 2]
add_item(my_list, 3)
print(my_list) # [1, 2, 3]
This is convenient but dangerous — any function might modify your data unexpectedly. Rust makes mutation explicit with &mut.
The exclusivity rule
Rust enforces a critical safety rule: you can have many shared references OR one mutable reference, but not both at the same time.
let mut s = String::from("hello");
let r1 = &s; // shared borrow
let r2 = &s; // another shared borrow — OK
// let r3 = &mut s; // ERROR: can't borrow mutably while shared borrows exist
println!("{} {}", r1, r2);
// r1 and r2 are no longer used after this point
let r3 = &mut s; // OK now — no active shared borrows
r3.push_str(" world");
Why this matters
This rule prevents data races at compile time. In Python:
items = [1, 2, 3]
for item in items:
if item == 2:
items.remove(item) # modifying while iterating — bug!
Rust won't let you hold a shared reference (the iterator) while also holding a mutable reference (to remove items).
The mut keyword
Note that both the variable AND the borrow must be mutable:
let mut x = 5; // variable must be mut
let r = &mut x; // borrow must be &mut
*r += 1; // dereference to modify
Login to see the full task and start coding.
Topics
This is a premium exercise
Log in to unlock the full exercise and start coding.
Login to access this exercise