How Does Ownership Work with Function Arguments in Rust?

Passing values moves ownership to the function, while passing references allows borrowing without transferring ownership.

Passing a value to a function moves ownership to the function, making the original variable unusable unless the type implements Copy. To keep using the original variable, pass a reference (&T) instead of the value itself.

fn main() {
    let s = String::from("hello");
    takes_ownership(s); // s is moved, invalid here
    // println!("{s}"); // Error: use of moved value
}

fn takes_ownership(some_string: String) {
    println!("{some_string}");
}

To keep using the original variable, pass a reference instead:

fn main() {
    let s = String::from("hello");
    let len = calculate_length(&s); // s is borrowed, still valid
    println!("{s}"); // OK
}

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