CodeBlanks Logo Icon CodeBlanks

Capturing

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 move is written).
let mut sayac = 0;
let mut artir = || sayac += 1;   // captures &mut sayac
artir();
artir();
println!("{sayac}");             // 2

A 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 Ece

Read-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

main.rs
fn main() {
    // buraya yaz
}

Sample solution

main.rs
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

Question
let ad = String::from("Ece");
let selam = ____ || format!("Merhaba {ad}");
Answer
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

All lessons in Intermediate