2015-06-17 12 views
9

Sto provando a scrivere un codice a matrice veloce in Rust e per fare questo è necessario assicurarsi che i loop siano srotolati. C'è un modo per creare un ciclo per la compilazione? Per esempio: VoglioPosso creare una macro che srotoli i loop?

unroll_loop!(f, a, 3); 

per generare

f(a, 0); 
f(a, 1); 
f(a, 2); 
+2

Penso che si possa scrivere un'estensione di sintassi per questo, ma i normali macro "macro_rules'-non ti aiuteranno perché non hanno alcun tipo di variabile o numero a loro disposizione. –

risposta

9

Beh, sorta di.

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)); 
} 

Si potrebbe essere tentati di chiedere "perché non basta usare unroll!($i-1, |$i| $s) per il caso ricorsivo?". Questo perché i macro non possono fare matematica. In realtà, non possono fare qualsiasi modulo di valutazione di qualsiasi. Sei fondamentalmente limitato alla manipolazione simbolica.

Macro anche non può interagire con i tipi o valori in qualsiasi modo, il che significa il seguente non funziona, e non può essere fatto funzionare:

const N: usize = 3; 
unroll!(N, |i| println!("i: {}", i)); 

Quindi, si possibile fare questo , ma solo per interi letterali, e devi scrivere un caso esplicito nella macro per ogni intero che vuoi essere in grado di usare.

+0

Solo per coloro che non sono a conoscenza dei plug-in del compilatore di Rust: Una possibile soluzione a ciò che funziona con numeri arbitrari (ma comunque in tempo utile alla compilazione) sarebbe implementare un plug-in del compilatore che esponga una macro 'srotoli! (...)' con la stessa semantica. I plugin non sono ancora stabili, comunque. – Regexident

Problemi correlati