Nun, Art zu erzeugen.
macro_rules! unroll {
(0, |$i:ident| $s:stmt) => {};
(1, |$i:ident| $s:stmt) => {{ let $i: usize = 0; $s; }};
(2, |$i:ident| $s:stmt) => {{ unroll!(1, |$i| $s); let $i: usize = 1; $s; }};
(3, |$i:ident| $s:stmt) => {{ unroll!(2, |$i| $s); let $i: usize = 2; $s; }};
(4, |$i:ident| $s:stmt) => {{ unroll!(3, |$i| $s); let $i: usize = 3; $s; }};
// ...
}
fn main() {
unroll!(3, |i| println!("i: {}", i));
}
Sie könnten versucht sein, zu fragen, „warum Sie unroll!($i-1, |$i| $s)
einfach nicht für die rekursive Fall verwenden?“. Dies liegt daran, Makros können nicht Mathe tun. In der Tat können sie keine Form der Bewertung was auch immer tun. Sie sind grundsätzlich auf symbolische Manipulation beschränkt.
Makros können auch nicht mit Typen oder Werte in irgendeiner Weise in Wechselwirkung treten, was bedeutet, dass die folgenden nicht funktioniert, und nicht gemacht werden kann arbeiten:
const N: usize = 3;
unroll!(N, |i| println!("i: {}", i));
Also, Sie können dies tun , aber nur für literale Ganzzahlen, und Sie müssen einen expliziten Fall in das Makro schreiben, damit jede ganze Zahl verwendet werden kann.
Ich denke, dass Sie eine Syntaxerweiterung dafür schreiben können, aber normale 'macro_rules'-Makros werden Ihnen nicht helfen, weil ihnen keine Arten von Variablen oder Nummern zur Verfügung stehen. –