macro_rules! enclose { [ // (a, b) move || true ( $($enc_args:tt)* ) move || $($b:tt)* ] => { ... }; [ // (a, b) move |c, d| true ( $($enc_args:tt)* ) move | $($args:tt),* | $($b:tt)* ] => { ... }; [ // (a, b) || true ( $($enc_args:tt)* ) || $($b:tt)* ] => { ... }; [ // (a, b) |c, d| true ( $($enc_args:tt)* ) | $($args:tt),* | $($b:tt)* ] => { ... }; [ // (a, b) true ( $($enc_args:tt)* ) $($all:tt)* ] => { ... }; [] => { ... }; }
Expand description
A macro for creating a closure, as well as cloning, copying values into the closure.
§Args Support
A list of all possible arguments that can be written, separated by commas, in the arguments to the macro.
§.clone()
operation
// (a => mut b: String) will be converted to (let mut b: String = a.clone();)
// (b => mut b)
// (a => b: usize)
// (a => b)
// (mut a: String)
// (mut a)
// (a: String)
// (a)
§*copy
operation
// (*a => mut b: &str) will be converted to (let mut b: &str = *a;)
// (*a => mut b)
// (*a => b: &str)
// (*a => b)
// (mut *a: &str)
// (mut *a)
// (*a: &str)
// (*a)
§let ref mut a = b;
(ref
) operation
// (ref mut a: String) will be converted to (let ref mut a: String = a;)
// (ref mut a)
// (ref a: String)
// (ref a)
// (ref a => mut b: String)
// (ref a => mut b)
// (ref a => b: String)
// (ref a => b)
§(1+1)
(expr) operation
// (@(1+1) => mut b: usize) will be converted to (let mut b: usize = (1+1);)
// (@(1+1) => mut b)
// (@(1+1) => b: usize)
// (@(1+1) => b)
§let a = b;
(move) operation
// (move a => mut b: String) will be converted to (let mut b: String = a;)
// (move a => mut b)
// (move a => mut b)
// (move a => b: String)
// (move a => b)
// (move mut a: String)
// (move mut a)
// (move a: String)
// (move a)
§{println!("test");}
(run) operation
// { panic!("12"); }
§Example
§JustUse
use enclose::enclose;
fn main() {
let clone_data = 0;
let add_data = 100;
my_enclose(enclose!((mut clone_data, add_data) || {
// (mut clone_data, add_data) ->
// let mut clone_data = clone_data.clone();
// let add_data = add_data.clone();
println!("#0 {:?}", clone_data);
clone_data += add_data;
println!("#1 {:?}", clone_data);
assert_eq!(clone_data, 100);
}));
assert_eq!(clone_data, 0);
}
#[inline]
fn my_enclose<F: FnOnce() -> R, R>(a: F) -> R {
a()
}
§Expr
use enclose::enclose;
use std::sync::Arc;
fn main() {
let clone_data = Arc::new(0);
let add_data = Arc::new(100);
// I also note that any expressions can be used, but the main thing is to
// put the @ symbol at the beginning of the variable, and not forget to assign
// a new name to the variable using =>.
my_enclose(
enclose!((@*clone_data => mut clone_data: usize, @*(add_data.clone()) => add_data) || {
// (@*clone_data => mut clone_data, @*(add_data.clone()) => add_data) ->
// let mut clone_data = *clone_data;
// let add_data = *(add_data.clone());
println!("#0 {:?}", clone_data);
clone_data += add_data;
println!("#1 {:?}", clone_data);
assert_eq!(clone_data, 100);
}),
);
assert_eq!(*clone_data, 0);
}
#[inline]
fn my_enclose<F: FnOnce() -> R, R>(a: F) -> R {
a()
}