← Back to Rust Course | Chapter 5: Ownership | Lesson 6 of 6

Ownership and Functions

When you hand a value to a function, you're often giving it away for good, unless you ask for it back.
Syntax
rust
fn take(param: Type) {
    // takes ownership
}

fn give() -> Type {
    // returns ownership
}

Passing Ownership Into a Function

When a non-Copy value like a String is passed by value into a function, ownership moves into that function's parameter, and the caller can no longer use the original variable afterward.

Example: Passing Ownership Into a Function

markup
// Define the function `consume` taking `s`
fn consume(s: String) {
    // Print "Consumed: {}" to the console, substituting in `s` (with a trailing newline)
    println!("Consumed: {}", s);
}

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `text`, set to `String::from("gift")`
    let text = String::from("gift");
    consume(text);
}

Returning Ownership

A function can transfer ownership of a value back to its caller simply by returning it as the final expression, letting the caller keep using the data under a new binding.

Example: Returning Ownership

markup
// Define the function `create_greeting` with no parameters and returning a String
fn create_greeting() -> String {
    String::from("Hello from a function")
}

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `greeting`, set to `create_greeting()`
    let greeting = create_greeting();
    // Print "{}" to the console, substituting in `greeting` (with a trailing newline)
    println!("{}", greeting);
}

Passing Ownership In and Returning It Back Out

A function can accept ownership of a value, use it, and then return it again, effectively "borrowing" it for the duration of the call through moves rather than references.

Example: Passing Ownership In and Returning It Back Out

markup
// Define the function `add_exclamation` taking `s` and returning a String
fn add_exclamation(mut s: String) -> String {
    // Append `'!'` to `s`
    s.push('!');
    s
}

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `phrase`, set to `String::from("Rust is great")`
    let phrase = String::from("Rust is great");
    // Declare an immutable variable `phrase`, set to `add_exclamation(phrase)`
    let phrase = add_exclamation(phrase);
    // Print "{}" to the console, substituting in `phrase` (with a trailing newline)
    println!("{}", phrase);
}

Avoiding Unnecessary Moves with References

Instead of moving ownership every time data needs to be read, a function can accept a reference (covered in the next chapter), letting the caller keep using its original variable after the call.

Example: Avoiding Unnecessary Moves with References

markup
// Define the function `print_length` taking `s`
fn print_length(s: &String) {
    // Print "Length is {}" to the console, substituting in `s.len()` (with a trailing newline)
    println!("Length is {}", s.len());
}

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `word`, set to `String::from("borrowed")`
    let word = String::from("borrowed");
    print_length(&word);
    // Print "Still usable: {}" to the console, substituting in `word` (with a trailing newline)
    println!("Still usable: {}", word);
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Passing a String into a function by value and then trying to use it again in the caller afterward.
  2. Not realizing that returning a value from a function transfers ownership back out to the caller.
  3. Overusing owned parameters (String instead of &str) in functions that only need to read data temporarily.
Chapter Summary
  • Passing a non-Copy value into a function by value moves ownership into that function.
  • A function can return ownership of a value, transferring it back to the caller.
  • Tuples can be used to return multiple values, including handing back a value alongside a computed result.
  • Accepting a reference instead of an owned value lets a function use data temporarily without taking ownership.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.