Ownership and Functions
In this page:
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
// 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);
}
Login to try C/C++/Java/PHP code in the editor
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
// 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);
}
Login to try C/C++/Java/PHP code in the editor
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
// 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);
}
Login to try C/C++/Java/PHP code in the editor
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
// 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);
}
Login to try C/C++/Java/PHP code in the editor
- Passing a
Stringinto a function by value and then trying to use it again in the caller afterward. - Not realizing that returning a value from a function transfers ownership back out to the caller.
- Overusing owned parameters (
Stringinstead of&str) in functions that only need to read data temporarily.
- Passing a non-
Copyvalue 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: