Functions and ownership
- Rust course
- Beginner
- Lesson 45/115
- 4 min
See how passing a value into a function affects ownership.
Functions and ownership
Passing a value to a function is like assignment: non-Copy types are moved into the function and the caller loses them:
fn yazdir(s: String) {
println!("{s}");
} // s is dropped here
let ad = String::from("Ada");
yazdir(ad);
// println!("{ad}"); // error: ad was moved
let n = 5;
kare(n); // the i32 is copied, n is still validIf the function only reads the value, it should take a reference (&String or &str) instead of ownership.
When to take ownership
If a function will store the value (put it in a struct field, push it to a vector), taking ownership is natural: fn ekle(&mut self, ad: String). If it transforms the value and returns a new one, taking ownership also avoids a needless copy: fn buyut(mut s: String) -> String. Otherwise borrowing is preferred.
Practice A borrowing function
Write fn uzunluk(s: &str) -> usize. Call uzunluk(&ad) for let ad = String::from("Ada Lovelace");, then print println!("{} {}", ad, n); to show you can still use ad.
Starter code
fn main() {
// buraya yaz
}Sample solution
fn uzunluk(s: &str) -> usize {
s.len()
}
fn main() {
let ad = String::from("Ada Lovelace");
let n = uzunluk(&ad);
println!("{} {}", ad, n);
}Expected output
Ada Lovelace 12
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What is the problem with the signature <code>fn uzunluk(s: String) -> usize</code>?
- It takes ownership just to read; the caller loses the String Correct answer
- usize is the wrong type
- A String's length can't be measured
- There is no problem
Explanation: fn uzunluk(s: &str) -> usize is better: it borrows and accepts both String and &str.
2 Borrowed parameter
fn uzunluk(s: ____) -> usize {
s.len()
}
fn uzunluk(s: &str) -> usize {
s.len()
}
Explanation: A &str parameter reads the text without taking ownership.
3 Signature and meaning
| Term | Meaning |
|---|---|
fn f(s: String) |
Takes ownership |
fn f(s: &str) |
Borrows |
fn f(n: i32) |
Takes a copy |
fn f(mut s: String) -> String |
Transforms and returns it |