Macro dichiarative (`macro_rules!`)
Impari a scrivere macro dichiarative per astrarre schemi di codice ripetitivi e generare codice in fase di compilazione.
Macro dichiarative (`macro_rules!`) è una lezione Learn Rust Coding gratuita su CoddyKit. Questa è la lezione 1 di 3. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Learn Rust Coding, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Learn Rust Coding include 3 lezioni in totale.
Che cosa sono le macro di Rust?
Le macro sono un modo per scrivere codice che scrive altro codice! Sono simili alle funzioni, ma operano sugli alberi sintattici, cioè sulla struttura del codice, invece che sui valori.
- Aiutano ad astrarre il codice ripetitivo.
- Consentono di creare linguaggi specifici per dominio (DSL) all'interno di Rust.
- Vengono eseguite al momento della compilazione ed espanse in normale codice Rust prima della compilazione.
Sintassi delle macro dichiarative
Le macro dichiarative di Rust usano la parola chiave macro_rules!. Definiscono un insieme di regole che corrispondono a specifici pattern di codice Rust.
Pensatele come a un pattern matching per frammenti di codice. Quando il compilatore incontra un'invocazione di macro, prova a far corrispondere l'input a una delle regole definite.
Il primo `macro_rules!`
Creiamo una macro molto semplice che stampa un saluto. Notate la parola chiave macro_rules! e la sintassi () => {}, che definisce una regola senza alcun pattern di input.
Provate a eseguire questo esempio:
macro_rules! greet {
() => {
println!("Hello from a macro!");
};
}
fn main() {
greet!(); // Call our macro!
}Acquisire l'input con i designator
Le macro possono ricevere input usando i "designator". Questi indicano alla macro quale tipo di sintassi Rust deve aspettarsi di acquisire.
$expr: un'espressione, ad esempio1 + 2o"hello"$ident: un identificatore, ad esempio il nome di una variabile o di una funzione$ty: un tipo, ad esempioi32oString$block: un blocco di codice, ad esempio{ ... }- ...e molti altri!
Macro con argomenti
Ecco una macro che riceve un'espressione ($e:expr) e ne stampa il valore. :expr è il designator.
Il valore acquisito in $e diventa quindi disponibile nel corpo della macro. La macro stringify! converte l'espressione nella relativa rappresentazione sotto forma di stringa.
macro_rules! debug_print {
($e:expr) => {
println!("Debug: {} = {:?}", stringify!($e), $e);
};
}
fn main() {
let x = 10;
debug_print!(x + 5);
debug_print!("Rust macros are fun");
}Gestire più input
E se voleste che una macro ricevesse più argomenti dello stesso tipo? Potete usare gli operatori di ripetizione: $()*.
$(): il contenuto interno è il pattern da ripetere.*: zero o più ripetizioni.+: una o più ripetizioni.- Potete anche specificare un separatore, ad esempio
$(...),*per elementi separati da virgole.
Macro con argomenti ripetuti
Creiamo una macro che riceve più espressioni separate da virgole e stampa ciascuna di esse individualmente. È una soluzione potente per creare strutture simili a liste.
macro_rules! print_all {
( $( $x:expr ),* ) => {
$( // This $(...)* repeats the `println!` call
println!("Item: {:?}", $x);
)*
};
}
fn main() {
print_all!(1, "hello", true, 3.14);
print_all!("Just one item");
}Comprendere l'hygiene delle macro
Le macro di Rust sono "hygienic", cioè rispettano l'hygiene. Questo significa che le variabili definite all'interno di una macro non entrano accidentalmente in conflitto con le variabili esterne alla macro, anche se hanno lo stesso nome.
Durante l'espansione, il compilatore rinomina internamente gli elementi per impedire effetti collaterali indesiderati, rendendo le macro più sicure e prevedibili.
Come eseguire il debug delle macro
A volte le macro non vengono espanse come previsto. Rust offre un modo per visualizzare il codice espanso:
- Eseguite
cargo expand(è necessario installare lo strumentocargo-expand) - Usate direttamente
rustc --pretty expandedsul file sorgente.
In questo modo potete visualizzare il codice Rust grezzo generato dalla macro, uno strumento prezioso per il debug e per comprendere il comportamento delle macro complesse!
Quiz sul pattern matching delle macro
Considerate la seguente definizione di macro:
macro_rules! make_tuple {
( $x:expr, $y:expr ) => {
($x, $y)
};
}Quale delle seguenti righe verrebbe compilata correttamente e userebbe la macro make_tuple!?
Riepilogo: macro dichiarative
In questa lezione ha imparato a conoscere le macro dichiarative usando macro_rules!:
- Generano codice in fase di compilazione, astraendo i pattern ripetitivi.
- Usano il pattern matching per acquisire l'input in base alla sintassi.
- I designator come
$expre$identspecificano il tipo di sintassi previsto. - Gli operatori di ripetizione come
$()*gestiscono più argomenti con separatori flessibili. - Le macro sono igieniche e impediscono conflitti accidentali tra nomi.
Le macro sono uno strumento potente per ridurre il codice ripetitivo e creare API flessibili ed ergonomiche in Rust!
Domande Frequenti
La lezione «Macro dichiarative (`macro_rules!`)» è gratuita?
Sì — il testo completo di «Macro dichiarative (`macro_rules!`)» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Learn Rust Coding, passa a CoddyKit PRO. Il corso Learn Rust Coding include 3 lezioni in totale.
Cosa imparerò in «Macro dichiarative (`macro_rules!`)»?
Impari a scrivere macro dichiarative per astrarre schemi di codice ripetitivi e generare codice in fase di compilazione. Eserciti Learn Rust Coding con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Learn Rust Coding?
Non è richiesta alcuna esperienza precedente. Learn Rust Coding su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 3.
Quanto tempo richiede la lezione «Macro dichiarative (`macro_rules!`)»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Learn Rust Coding?
Sì. Ogni lezione Learn Rust Coding include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Macro dichiarative (`macro_rules!`)
- Macro procedurali: Derive e Function
- Interagire con Rust unsafe