Defer code to be executed at the end of the scope, much like defer
in Go.
fn main() {
later::defer! {
println!("World!");
}
println!("Hello");
}
- Access to local variables (see below)
- Drop guards are unnameable and cannot be passed to
mem::forget
- Async support
#![no_std]
compatible
- Only one defer per scope
The code snippet above shows how the defer macro can be used for running "freestanding" code (no access to locals), however sometimes access to local variables is needed.
In that case you can pass a closure to the macro. Note that the parameter names must match the variable names you would like to capture from the surrounding environment. The closure body can also be an async block, in which case it will be awaited.
fn main() {
let fut = std::future::ready(123);
// This runs when main exits
later::defer!(|fut: std::future::Ready<i32>| async {
println!("World = {}", fut.await);
});
println!("Hello");
}
Note: Async blocks requires the
async
feature. Enabling it in turn disablesno_std
support.
When capturing variables from the enclosing environment, they are cloned by default.
You can specify the move
keyword in front of the closure to move them rather than cloning, like so:
fn main() {
let foo = String::from("bar");
// vvvv
later::defer!(move |foo: String| {
println!("{foo}");
});
print!("-> ");
}
If you now try to use foo
after it's been moved into the defer
, compilation will fail.