macro_rules! mlambda {
(
@def ($dol:tt) [$([$x:ident])*][$([$y:ident, $($z:tt)*])*]
fn $name:ident($($args:tt)*) -> $ret:ty $body:block
) => { ... };
(@pre () [$($x:tt)*][$($y:tt)*] fn $name:ident($($args:tt)*) -> $ret:ty $body:block) => { ... };
(@pre () [$($x:tt)*][$($y:tt)*] fn $name:ident($($args:tt)*) $body:block) => { ... };
(@pre ($arg:ident $(:$ty:ty)?) [$($x:tt)*][$($y:tt)*] $($rest:tt)*) => { ... };
(@pre ($arg:ident $(:$ty:ty)?, $($args:tt)*) [$($x:tt)*][$($y:tt)*] $($rest:tt)*) => { ... };
(fn $name:ident($($args:tt)*) $($rest:tt)*) => { ... };
}
Expand description
Macro that define closure like macro. Unlike closure, this macro localizes variable capture.
ยงExample
let graph: Vec<Vec<usize>> = vec![vec![1, 2], vec![2], vec![]];
let mut deq = std::collections::VecDeque::new();
let mut dist: Vec<usize> = vec![!0; 3];
mlambda!(
fn push(v: usize, cost: usize) {
if dist[v] > cost {
dist[v] = cost;
deq.push_back(v);
}
}
);
push!(0, 0);
while let Some(v) = deq.pop_front() {
for &to in &graph[v] {
push!(to, dist[v] + 1);
}
}
assert_eq!(vec![0, 1, 1], dist);