Makrod võimaldavad teil kirjutada koodi, mis kirjutab muud koodi. Tutvuge metaprogrammeerimise kummalise ja võimsa maailmaga.
Koodi genereerimine on funktsioon, mille leiate enamikust kaasaegsetest programmeerimiskeeltest. See võib aidata teil vähendada standardkoodi ja koodi dubleerimist, määratleda domeenispetsiifilisi keeli (DSL) ja rakendada uut süntaksit.
Rust pakub võimsat makrosüsteemi, mis võimaldab teil kompileerimise ajal koodi genereerida keerukamaks programmeerimiseks.
Sissejuhatus roostemakrodesse
Makrod on teatud tüüpi metaprogrammeerimine, mida saate kasutada koodi kirjutava koodi kirjutamiseks. Rustis on makro koodiosa, mis genereerib kompileerimise ajal muud koodi.
Roostemakrod on võimas funktsioon, mis võimaldab kirjutada koodi, mis genereerib kompileerimise ajal muud koodi korduvate toimingute automatiseerimiseks. Rusti makrod aitavad vähendada koodi dubleerimist ning suurendada koodi hooldatavust ja loetavust.
Makrode abil saate luua kõike alates lihtsatest koodilõikudest kuni teekide ja raamistikeni. Makrod erinevad
Rooste funktsioonid sest nad töötavad käitusajal pigem koodi kui andmete alusel.Makrode määratlemine roostes
Makrod saate määratleda nupuga makro_reeglid! makro. The makro_reeglid! makro võtab sisendiks mustri ja malli. Rust sobitab mustri sisendkoodiga ja kasutab väljundkoodi genereerimiseks malli.
Makrosid saab Rustis määratleda järgmiselt.
makro_reeglid! ütle Tere {
() => {
println!("Tere, Maailm!");
};
}
fnpeamine() {
ütle Tere!();
}
Kood määratleb a ütle Tere makro, mis genereerib koodi "Tere, maailm!" printimiseks. Kood vastab () süntaks tühja sisendi vastu ja println! makro genereerib väljundkoodi.
Siin on makro rakenduses käitamise tulemus peamine funktsioon:
Makrod võivad genereeritud koodi jaoks võtta sisestusargumente. Siin on makro, mis võtab ühe argumendi ja genereerib sõnumi printimiseks koodi:
makro_reeglid! say_message {
($sõnum: avaldis) => {
println!("{}", $sõnum);
};
}
The ütle_sõnum makro võtab $sõnum argument ja genereerib koodi argumendi printimiseks kasutades println! makro. The avald süntaks ühtib argumendiga mis tahes Rusti avaldise vastu.
Rooste makrode tüübid
Rust pakub kolme tüüpi makrosid. Iga makrotüüp teenib kindlaid eesmärke ning neil on oma süntaks ja piirangud.
Protseduurimakrod
Protseduurimakrosid peetakse kõige võimsamaks ja mitmekülgsemaks tüübiks. Protseduurimakrod võimaldavad teil määratleda kohandatud süntaksi, mis genereerib samaaegselt Rust-koodi. Protseduurimakrosid saate kasutada kohandatud tuletatud makrode, kohandatud atribuudilaadsete makrode ja kohandatud funktsioonilaadsete makrode loomiseks.
Struktuuride ja loenditunnuste automaatseks rakendamiseks kasutate kohandatud tuletatud makrosid. Sellised populaarsed paketid nagu Serde kasutavad Rusti andmestruktuuride jaoks serialiseerimis- ja deserialiseerimiskoodi genereerimiseks kohandatud tuletatud makrot.
Kohandatud atribuuditaolised makrod on mugavad Rusti koodile kohandatud märkuste lisamiseks. Veebiraamistik Rocket kasutab marsruutide lühidalt ja loetavalt määratlemiseks kohandatud atribuudilaadset makrot.
Uute Rust-avaldiste või -lausete määratlemiseks saate kasutada kohandatud funktsioonitaolisi makrosid. Lazy_static kast kasutab selle määratlemiseks kohandatud funktsioonitaolist makrot laisk-initsialiseeritud staatilised muutujad.
Kohandatud tuletatud makro määratleva protseduurilise makro määratlemiseks tehke järgmist.
kasutada proc_macro:: TokenStream;
kasutada tsitaat:: tsitaat;
kasutada syn::{DeriveInput, parse_macro_input};
The kasutada käskkirjad impordivad vajalikud kastid ja tüübid Rusti protseduurilise makro kirjutamiseks.
#[proc_macro_derive (MyTrait)]
pubifnminu_tuletatud_makro(sisend: TokenStream) -> TokenStream {
lase ast = parse_macro_input!(sisend nagu DeriveInput);
lase nimi = &ast.ident;lase gen = tsitaat! {
impl MyTrait jaoks #nimi {
// rakendamine siin
}
};
gen.into()
}
Programm määratleb protseduurilise makro, mis genereerib struktuuri või enumi tunnuse rakendamise. Programm kutsub makro koos nimega MyTrait struktuuri või enumi tuletusatribuudis. Makro võtab a TokenStream objekt sisendina, mis sisaldab koodi, mis on sõelutud abstraktsesse süntaksipuusse (AST) koos parse_macro_input! makro.
The nimi muutuja on tuletatud struktuuri või enumi identifikaator, the tsitaat! Makro loob uue AST-i, mis tähistab selle rakendamist MyTrait tüübi jaoks, mis lõpuks tagastatakse kui a TokenStream koos sisse meetod.
Makro kasutamiseks peate makro importima moodulist, milles te selle deklareerisite:
// eeldades, et deklareerisite makro moodulis my_macro_module
kasutada minu_makro_moodul:: minu_tuletatud_makro;
Makrot kasutava struktuuri või enumi deklareerimisel lisate #[tuletada (MyTrait)] atribuut deklaratsiooni ülaossa.
#[tuletada (MyTrait)]
struktuurMinuStruktuur {
// väljad siin
}
Atribuudiga struktuurideklaratsioon laieneb atribuudi rakendamiseks MyTrait struktuuri omadus:
impl MyTrait jaoks MyStruct {
// rakendamine siin
}
Rakendamine võimaldab teil kasutada meetodeid MyTrait tunnus peal MinuStruktuur juhtumid.
Atribuutide makrod
Atribuudimakrod on makrod, mida saate rakendada Rust-üksustele, nagu struktuurid, enumid, funktsioonid ja moodulid. Atribuudi makrod on atribuudi kujul, millele järgneb argumentide loend. Makro parsib argumendi, et genereerida Rust-kood.
Koodile kohandatud käitumisviiside ja märkuste lisamiseks kasutate atribuutimakrosid.
Siin on atribuudi makro, mis lisab Rust-struktuurile kohandatud atribuudi:
// moodulite importimine makro definitsiooni jaoks
kasutada proc_macro:: TokenStream;
kasutada tsitaat:: tsitaat;
kasutada syn::{parse_macro_input, DeriveInput, AttributeArgs};#[proc_macro_attribute]
pubifnminu_atribuut_makro(attr: TokenStream, üksus: TokenStream) -> TokenStream {
lase args = parse_macro_input!(attr nagu AttributeArgs);
lase input = parse_macro_input!(üks nagu DeriveInput);
lase nimi = &input.ident;lase gen = tsitaat! {
#sisend
impl #nimi {
// kohandatud käitumine siin
}
};
gen.into()
}
Makro võtab argumentide loendi ja struktuuri määratlus ja genereerib määratletud kohandatud käitumisega muudetud struktuuri.
Makro kasutab sisendiks kahte argumenti: makrole rakendatud atribuut (parsitakse koos parse_macro_input! makro) ja üksus (parsitakse parse_macro_input! makro). Makro kasutab tsitaat! makro koodi genereerimiseks, sealhulgas algne sisendüksus ja täiendav impl plokk, mis määrab kohandatud käitumise.
Lõpuks tagastab funktsioon loodud koodi kujul a TokenStream koos sisse () meetod.
Makroreeglid
Makroreeglid on kõige lihtsamad ja paindlikumad makrotüübid. Makroreeglid võimaldavad teil määratleda kohandatud süntaksi, mis laieneb kompileerimise ajal Rust-koodiks. Makroreeglid määratlevad kohandatud makrod, mis vastavad mis tahes roosteväljendusele või -avaldusele.
Makroreeglite abil saate luua standardkoodi, et abstraktselt võtta kokku madala taseme üksikasjad.
Siit saate teada, kuidas saate oma Rusti programmides makroreegleid määratleda ja kasutada.
makro_reeglid! make_vector {
( $( $x: expr ),* ) => {
{
lasemut v = Vec::uus();
$(
v.push($x);
)*
v
}
};
}
fnpeamine() {
lase v = make_vector![1, 2, 3];
println!("{:?}", v); // prindib "[1, 2, 3]"
}
Programm määratleb a make_vector! makro, mis loob komadega eraldatud avaldiste loendist uue vektori peamine funktsiooni.
Makro sees ühtib mustri definitsioon makrole edastatud argumentidega. The $( $x: expr ),* süntaks sobib kõigile komadega eraldatud avaldistele, mis on identifitseeritud kui $x.
The $( ) laienduskoodi süntaks itereerub üle iga avaldise argumentide loendis, mis edastatakse makrole pärast sulgev sulg, mis näitab, et iteratsioonid peaksid jätkuma, kuni makro töötleb kõiki väljendid.
Korraldage oma roosteprojekte tõhusalt
Roostemakrod parandavad koodi organiseerimist, võimaldades teil määratleda korduvkasutatavaid koodimustreid ja abstraktsioone. Makrod aitavad teil kirjutada kokkuvõtlikumat ja väljendusrikkamat koodi ilma projekti erinevates osades dubleerimiseta.
Samuti saate korraldada Rust programmid kastidesse ja moodulitesse, et tagada parem koodi korraldamine, korduvkasutatavus ning koostoime teiste kastide ja moodulitega.