Course contentsShow
← Rust
Lesson 230 of 1,9103. Borrowing and ReferencesFree lesson

Borrowing in Closures

Understand how closures capture variables by reference for reading and writing.

In this lesson, you will learn how closures capture variables from their surrounding scope by borrowing them instead of taking ownership.

The Invisible Bridge

A closure is a function-like block that can "capture" variables from the code where it is defined. When you define a closure, Rust is smart enough to look at how you use those captured variables and automatically decides whether to borrow them as shared references (&T) or mutable references (&mut T).

Because closures are just pieces of code that might run later, they don't necessarily take ownership of the values they use. Instead, they create a "bridge" to the existing data.

Borrowing for Reading

If you only need to read a variable inside your closure, Rust captures it as an immutable reference:

let message = String::from("Hello");

// The closure captures 'message' by shared reference (&T)
let print_message = || println!("{}", message);

print_message();
// 'message' is still available here because it was only borrowed!
println!("Still have access: {}", message);

Borrowing for Writing

If you need to change a variable inside your closure, you must declare the closure as mut, and the captured variable must also be mutable. Rust will then capture it as a mutable reference (&mut T):

let mut counter = 0;

// We use 'mut' here because we intend to modify the captured variable
let mut increment = || {
    counter += 1;
};

increment();
increment();

println!("Counter is now: {}", counter); // Output: 2

The Borrow Checker Still Applies

Even inside a closure, the rules of borrowing remain strict. If you have created a closure that holds a mutable borrow of a variable, the Borrow Checker will prevent you from using that variable anywhere else until the closure is finished or goes out of scope. The closure acts just like any other function receiving a reference; it must respect the rules of exclusive mutability to ensure memory safety.

Key Takeaway: Closures automatically borrow variables from their environment as shared or mutable references based on how they are used, adhering to the same borrow rules that govern standard functions.