Higher-Order Functions
Functions that take functions (closures) as arguments or return them enable composition and reusable control patterns.
Search across all documentation pages
Functions that take functions (closures) as arguments or return them enable composition and reusable control patterns.
fn twice<F: Fn(i32) -> i32>(f: F, x: i32) -> i32 {
f(f(x))
}
fn main() {
println!("{}", twice(|n| n + 1, 0));
}When to reach for this: map/filter style utilities, middleware, and custom iteration.
fn retry<F: FnMut() -> bool>(mut f: F, max: u32) -> bool {
for _ in 0..max {
if f() { return true; }
}
false
}
fn main() {
let mut attempts = 0;
let ok = retry(|| { attempts += 1; attempts >= 3 }, 5);
println!("{ok} {attempts}");
}What this demonstrates:
FnMut for mutating attempt counter in closureIterator adapters are higher-order: map, filter take closures. Compose small HOFs for clarity.
FnMut if needed.| Alternative | Use When | Don't Use When |
|---|---|---|
| Trait object callback | Runtime plugins | Static generics work |
| Inline for loop | Simple one-off | Reused pattern |
| Iterator adapters | Collection transforms | Imperative retry |
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Reviewed by Chris St. John·Last updated Jul 16, 2026