E sad, posle 5 godina prvi put sam resio da napravim makro u rust-u ;)
Ne znam zasto sam izbegavao ovaj feature, valjda zato sto izbegavam makroe u C/C++,
ali Rust makroi su potpuno druga stvar.
Elem, posto Rust nema for petlju nego samo for range pelju resio sam da napravim makro koji ce
ovo da omoguci.
Code:
macro_rules! for_loop{
((;;$(;$lbl:tt)*)$bl:block)=>{
$($lbl:)* loop {$bl}
};
((;$cond:expr;$(;$lbl:tt)*)$bl:block)=>{
$($lbl:)* while $cond {$bl}
};
((;$cond:expr;$inc:expr$(;$lbl:tt)*)$bl:block)=>{
$($lbl:)* while $cond {
$bl;
$inc;
}
};
(($($vars:stmt),*;$cond:expr;$inc:expr$(;$lbl:tt)*)$bl:block) => {{
$(
$vars;
)*
$($lbl:)* while $cond {
$bl;
$inc;
}
}};
}
$()* znaci da se stvar unutar zagrada moze ponavljati vise puta ili nijednom.
tt je bilo koji token, block samo mu ime kaze, expr je izraz, a stmt recenica tipa let a = 5`.
Sve makro varijable pocinju sa $var:tip
Dakle ovo je jasno.
Koriscenje izgleda ovako:
Code:
fn main(){
for_loop!((let mut a=0,let b=10,let mut c=2;a<b;{a+=c;c+=1}){
println!("{} {} {}",a,b,c);
});
for_loop!((let (mut a,b,mut c)=(0,10,2);a<b;{a+=c;c+=1}){
println!("{} {} {}",a,b,c);
});
let (mut a,b,mut c)=(0,10,2);
for_loop!((;a<b;{a+=c;c+=1}){
println!("{} {} {}",a,b,c);
});
for_loop!((;a>-20;;'outer){
println!("outer");
for_loop!((;;){
println!("{} {} {}",a,b,c);
if a < 1 { break 'outer}
a-=c;
continue 'outer;
})
})
}
Znaci pokriva sve slucajeve kao for petlja u C++ + ima opcionu labelu za petlju.
Prilicno sam impresioniram sta sve moze da se izvede preko makroa u Rustu ;)