Pybites Logo Rust Platform

Ownership and Borrowing

Medium +3 pts

🎯 In Python, you never think about who "owns" a value:

def label(item):
    return f"Product: {item}"

item = "Laptop"
tag = label(item)
print(item)  # still works — item wasn't consumed

Every variable is a reference to a garbage-collected object. Pass it to a function, return it, store it — the GC handles cleanup.

Rust has no garbage collector. Instead, it uses ownership — every value has exactly one owner, and when the owner goes out of scope, the value is dropped (freed). When you pass a value to a function, you transfer ownership (a "move"):

fn announce(item: String) -> String {
    format!("Now selling: {}!", item)
}

let item = String::from("Laptop");
let msg = announce(item);
// item is gone — it was moved into announce()

Borrowing: using without owning

To use a value without taking ownership, you borrow it with &:

fn length(s: &String) -> usize {
    s.len()
}

let name = String::from("Alice");
let len = length(&name);    // borrow with &
println!("{}", name);       // still works — name wasn't moved

&String is a shared reference — read-only access. The original owner keeps the value.

Mutable borrowing

To modify a borrowed value, use &mut:

fn append_exclaim(s: &mut String) {
    s.push('!');
}

let mut msg = String::from("hello");
append_exclaim(&mut msg);
assert_eq!(msg, "hello!");

Rust's rules: you can have many shared borrows (&T) or one mutable borrow (&mut T), but not both at the same time. This prevents data races at compile time.

Login to see the full task and start coding.

This is a premium exercise

Log in to unlock the full exercise and start coding.

Login to access this exercise