liveBook · Manning

Closure

As explained in Idiomatic Rust

A closure is an anonymous function value that can accept parameters and capture values from its surrounding environment.

A closure is a function value written where it is needed. In Rust, parameters go between pipes, followed by an expression or block: `|| println!("Bark!")` takes no arguments, while `|value| value + 1` returns an incremented value. The compiler can infer parameter types, and a single-expression body needs no braces. section 3.2.1

Closures become especially useful when a higher-order function lets its caller supply an operation. An iterator’s `map()` can take `|v| v.to_string()` to transform each item; a matching named function can be supplied instead. The transformation is lazy until the iterator is evaluated, for example with `collect()`. section 3.2.1 section 3.2.5

A closure can also capture a value from its surroundings. How it uses captured values determines its callable traits: `Fn` supports repeated calls without consuming them; `FnMut` supports repeated calls with mutable access; `FnOnce` covers a call that consumes a capture. These traits let generic functions accept closures with different capture behavior. section 3.2.2

Listing 3.3 Closure with move
let consumable = String::from("cookie");
let consumer = move || consumable;
consumer();
// consumer(); error!

Moving a string into a closure and returning it consumes the captured value on the first call. Uncommenting the second `consumer()` call produces a moved-value error. section 3.2.2

Use `move` when you want to make ownership transfer into a closure explicit; without it, Rust infers how to capture the value. Watch the surrounding operation as well as the closure: `flat_map(|v| v.parse::<i32>())` discards parse errors when it flattens each `Result`. If those errors matter, retain them instead. section 3.2.2 section 3.2.5

How Idiomatic Rust covers it

How deep it goes
Explains syntax, inferred parameters, capture, callable traits, and ownership errors through small examples.
Examples
Shows incrementing a value, consuming a captured string, and mapping integers to strings.
What it assumes
Builds on generics and traits while teaching closure syntax from simple, parameter-free examples.
What you can do after
Apply it via Rust closures and iterator methods while recognizing when capture consumes a value or parsing drops errors.
How it connects
Connects closures to higher-order functions, iterators, generics, ownership, and functional programming.

Also explained in

Compare how 20 books explain closure →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Idiomatic Rust. The section links point to the parts of the book it draws on.