closure_attr
This crate provides an attribute to simplify closure captures.
Example
use ;
// Expects a 'static callback
// Enable use of #[closure(...)]
example;
It expands to:
use_callback({
let s = s.clone(); // Clone requested by attribute
let i = i.clone(); // Clone requested by attribute
move || {
{... code to force whole captures ...}
s.replace(format!("Hello, world! {}", i.get()));
i.set(i.get() + 1);
}
});
Capture types
| Syntax | Description |
|---|---|
clone <ident> |
Clone the variable |
clone mut <ident> |
Clone the variable and make it mutable |
ref <ident> |
Take a reference to the variable |
ref mut <ident> |
Take a mutable reference to the variable |
move <ident> |
Move the variable into the closure |
move mut <ident> |
Move the variable into the closure and make it mutable |
weak <ident> |
See below |
weak
weak uses weak pointers to help break up reference cycles. It downgrades
an Rc or Arc pointer (or anything which implements [Downgrade] and [Upgrade])
and captures it. The transformed closure upgrades the pointer when it is called.
If any upgrade fails, it skips executing the body and returns Default::default().
use ;
example;
This Expands to:
let closure = {
let r = ::closure_attr::Downgrade::downgrade(&r);
let a = ::closure_attr::Downgrade::downgrade(&a);
move || {
(|| {
let r = ::closure_attr::Upgrade::upgrade(&r)?;
let a = ::closure_attr::Upgrade::upgrade(&a)?;
Some((|| *r * *a)())
})()
.unwrap_or_default()
}
};
Whole captures
The capture attribute captures whole variables. For example, this code without the attribute produces an error:
fn send<T: Send>(_: T) {}
struct SendPointer(*const ());
unsafe impl Send for SendPointer {}
fn f() {
let p = SendPointer(std::ptr::null());
send(
move || {
p.0;
},
);
}
error[E0277]: `*const ()` cannot be sent between threads safely
A workaround:
#[closure_attr::with_closure]
fn f() {
let p = SendPointer(std::ptr::null());
send(
#[closure(move p)]
move || {
p.0;
},
);
}
This is equivalent to inserting let _ = &p; into the body of the closure.
License
This work is dual-licensed under MIT and Apache 2.0. You can choose between one of them if you use this work.
SPDX-License-Identifier: MIT OR Apache-2.0