Capturing
- Rust course
- Intermediate
- Lesson 44/115
- 4 min
Learn how closures capture environment variables.
Capturing
A closure captures variables from its environment in one of three ways, and the compiler picks the weakest one needed:
- immutable borrow (if it only reads),
- mutable borrow (if it modifies),
- ownership (if it consumes the value, or if
moveis written).
let mut sayac = 0;
let mut artir = || sayac += 1; // captures &mut sayac
artir();
artir();
println!("{sayac}"); // 2A closure capturing mutably must itself be mut; while the closure is alive, sayac can't be used elsewhere.
Ownership with move
move is used when the closure must live longer than the scope where it is defined:
let ad = String::from("Ece");
let selam = move || format!("Merhaba {ad}");
// println!("{ad}"); // error: ad was moved into the closure
println!("{}", selam()); // Merhaba EceRead-only Copy values (like i32) are copied with move; the original variable can still be used.
Practice Kinds of capture
Increment let mut sayac = 0; twice with a closure and print sayac. Then write a closure that takes String::from("Ece") with move and returns Merhaba Ece, and print its result.
Starter code
fn main() {
// buraya yaz
}Sample solution
fn main() {
let mut sayac = 0;
let mut artir = || sayac += 1;
artir();
artir();
println!("{}", sayac);
let ad = String::from("Ece");
let selam = move || format!("Merhaba {ad}");
println!("{}", selam());
}Expected output
2 Merhaba Ece
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What does the <code>move</code> keyword do?
- Prevents copying variables
- Transfers ownership of the captured variables into the closure Correct answer
- Moves the closure to another file
- Speeds the closure up
Explanation: Copy types are copied, others are moved. It's needed for threads and closures returned from functions.
2 Take ownership
let ad = String::from("Ece");
let selam = ____ || format!("Merhaba {ad}");
let ad = String::from("Ece");
let selam = move || format!("Merhaba {ad}");
Explanation: move moves the captured values into the closure.
3 Closure body and capture
| Term | Meaning |
|---|---|
|| println!("{x}") |
&x |
|| x += 1 |
&mut x |
|| drop(s) |
s (ownership) |
move || x |
Copy/ownership of x |