Makron avulla voit kirjoittaa koodia, joka kirjoittaa toisen koodin. Ota selvää metaohjelmoinnin oudosta ja voimakkaasta maailmasta.
Koodin luominen on ominaisuus, joka löytyy useimmista nykyaikaisista ohjelmointikielistä. Se voi auttaa sinua vähentämään vakiokoodia ja koodin päällekkäisyyttä, määrittelemään verkkoaluekohtaisia kieliä (DSL) ja ottamaan käyttöön uuden syntaksin.
Rust tarjoaa tehokkaan makrojärjestelmän, jonka avulla voit luoda koodia käännöshetkellä kehittyneempää ohjelmointia varten.
Johdatus ruostemakroihin
Makrot ovat eräänlainen metaohjelmointi, jota voit hyödyntää kirjoittaaksesi koodia, joka kirjoittaa koodia. Rustissa makro on koodinpätkä, joka luo muun koodin käännöshetkellä.
Rust-makrot ovat tehokas ominaisuus, jonka avulla voit kirjoittaa koodia, joka luo muun koodin käännöshetkellä toistuvien tehtävien automatisoimiseksi. Rustin makrot auttavat vähentämään koodin päällekkäisyyttä ja lisäämään koodin ylläpidettävyyttä ja luettavuutta.
Makrojen avulla voit luoda mitä tahansa yksinkertaisista koodinpätkistä kirjastoihin ja kehyksiin. Makrot eroavat
Ruosteen toiminnot koska ne toimivat koodilla eikä datalla ajon aikana.Makron määrittely ruosteessa
Voit määrittää makrot makro_säännöt! makro. The makro_säännöt! makro ottaa syötteeksi kuvion ja mallin. Rust sovittaa kuvion syöttökoodiin ja käyttää mallia tuloskoodin luomiseen.
Näin voit määrittää makrot Rustissa:
makro_säännöt! sano Hei {
() => {
println!("Hei maailma!");
};
}
fnpää() {
sano Hei!();
}
Koodi määrittelee a sano Hei makro, joka luo koodin, jolla tulostetaan "Hei, maailma!". Koodi vastaa () syntaksi tyhjää syötettä vastaan ja println! makro luo tuloskoodin.
Tässä on makron suorittamisen tulos pää toiminto:
Makrot voivat ottaa syöteargumentteja luodulle koodille. Tässä on makro, joka ottaa yhden argumentin ja luo koodin viestin tulostamiseksi:
makro_säännöt! sano_viesti {
($viesti: expr) => {
println!("{}", $viesti);
};
}
The sano_viesti makro vie $viesti argumentti ja luo koodin argumentin tulostamiseksi käyttämällä println! makro. The expr syntaksi vastaa argumenttia mitä tahansa Rust-lauseketta vastaan.
Ruostemakrotyypit
Rust tarjoaa kolmenlaisia makroja. Jokainen makrotyyppi palvelee tiettyjä tarkoituksia, ja niillä on syntaksi ja rajoituksensa.
Proseduurimakrot
Proseduurimakroja pidetään tehokkaimpana ja monipuolisimpana tyyppinä. Proseduurimakrojen avulla voit määrittää mukautetun syntaksin, joka luo Rust-koodin samanaikaisesti. Proseduurimakrojen avulla voit luoda mukautettuja johdettuja makroja, mukautettuja attribuuttimakroja ja mukautettuja funktion kaltaisia makroja.
Käytät mukautettuja johdannaismakroja toteuttaaksesi rakenteet ja enum-ominaisuudet automaattisesti. Suositut paketit, kuten Serde, käyttävät mukautettua johdannaismakroa sarjoitus- ja deserialisointikoodin luomiseen Rust-tietorakenteille.
Mukautetut määritteen kaltaiset makrot ovat käteviä mukautettujen huomautusten lisäämiseen Rust-koodiin. Rocket-verkkokehys käyttää mukautettua attribuuttimaista makroa reittien määrittelemiseen tiiviisti ja luettavasti.
Voit käyttää mukautettuja funktion kaltaisia makroja uusien Rust-lausekkeiden tai lausekkeiden määrittämiseen. Lazy_static crate käyttää mukautettua funktion kaltaista makroa määrittämään laiska-alustettu staattiset muuttujat.
Näin voit määrittää prosessimakron, joka määrittää mukautetun johdetun makron:
käyttää proc_macro:: TokenStream;
käyttää lainaus:: lainaus;
käyttää syn::{Johdonsyöte, jäsennysmakron_tulo};
The käyttää direktiivit tuovat tarvittavat laatikot ja tyypit Rust-proseduurimakron kirjoittamiseen.
#[proc_macro_derive (MyTrait)]
pubfnmy_derive_macro(syöttö: TokenStream) -> TokenStream {
antaa ast = parse_macro_input!(syöttö kuten DeriveInput);
antaa nimi = &ast.ident;antaa gen = lainaus! {
impl MyTrait varten #nimi {
// toteutus täällä
}
};
gen.into()
}
Ohjelma määrittelee proseduurimakron, joka luo ominaisuuden toteutuksen structille tai enumille. Ohjelma kutsuu makron nimellä MyTrait structin tai enumin derivattribuutissa. Makro ottaa a TokenStream -objekti syötteenä, joka sisältää koodin jäsennettynä abstraktiin syntaksipuuhun (AST) komennolla parse_macro_input! makro.
The nimi muuttuja on johdettu rakenne- tai enum-tunniste, the lainata! Makro luo uuden AST: n, joka edustaa toteutusta MyTrait tyypille, joka lopulta palautetaan nimellä a TokenStream kanssa sisään menetelmä.
Jos haluat käyttää makroa, sinun on tuotava makro siitä moduulista, jossa sen määritit:
// olettaen, että olet ilmoittanut makron my_macro_module-moduulissa
käyttää my_macro_module:: my_derive_macro;
Kun määrität makroa käyttävän rakenteen tai enum: n, lisäät #[derive (MyTrait)] määrite ilmoituksen alkuun.
#[derive (MyTrait)]
structMyStruct {
// kentät tänne
}
Attribuutilla varustettu struct-ilmoitus laajenee sovelluksen toteuttamiseksi MyTrait rakenteen ominaisuus:
impl MyTrait varten MyStruct {
// toteutus täällä
}
Toteutus mahdollistaa menetelmien käytön MyTrait ominaisuus päällä MyStruct tapauksia.
Attribuuttimakrot
Attribuuttimakrot ovat makroja, joita voit käyttää Rust-kohteisiin, kuten rakenteisiin, enumeihin, funktioihin ja moduuleihin. Attribuuttimakrot ovat attribuutin muodossa, jota seuraa argumenttiluettelo. Makro jäsentää argumentin ruostekoodin luomiseksi.
Voit lisätä koodiisi mukautettuja toimintoja ja huomautuksia attribuuttimakrojen avulla.
Tässä on attribuuttimakro, joka lisää mukautetun attribuutin Rust-rakenteeseen:
// moduulien tuonti makromäärittelyyn
käyttää proc_macro:: TokenStream;
käyttää lainaus:: lainaus;
käyttää syn::{parse_macro_input, DeriveInput, AttributeArgs};#[proc_macro_attribute]
pubfnmy_attribute_macro(attr: TokenStream, kohde: TokenStream) -> TokenStream {
antaa args = parse_macro_input!(attr kuten AttributeArgs);
antaa input = parse_macro_input!(kohde kuten DeriveInput);
antaa nimi = &input.ident;antaa gen = lainaus! {
#syöttö
impl #nimi {
// mukautettu käyttäytyminen täällä
}
};
gen.into()
}
Makro ottaa luettelon argumenteista ja rakenteen määritelmä ja luo muokatun rakenteen määritetyllä mukautetulla toiminnalla.
Makro ottaa syötteenä kaksi argumenttia: makroon sovellettavan attribuutin (jäsennys parse_macro_input! makro) ja alkio (jäsennys parse_macro_input! makro). Makro käyttää lainata! makro koodin luomiseen, mukaan lukien alkuperäinen syöttökohde ja ylimääräinen impl lohko, joka määrittää mukautetun toiminnan.
Lopuksi funktio palauttaa luodun koodin muodossa a TokenStream kanssa sisään () menetelmä.
Makrosäännöt
Makrosäännöt ovat yksinkertaisin ja joustavin makrotyyppi. Makrosääntöjen avulla voit määrittää mukautetun syntaksin, joka laajenee ruostekoodiksi käännösvaiheessa. Makrosäännöt määrittelevät mukautettuja makroja, jotka vastaavat mitä tahansa ruosteilmaisua tai -lausetta.
Käytät makrosääntöjä luomaan pohjakoodia matalan tason yksityiskohtien tiivistämiseen.
Näin voit määrittää ja käyttää makrosääntöjä Rust-ohjelmissasi:
makro_säännöt! make_vector {
( $( $x: expr ),* ) => {
{
antaamut v = Vec::Uusi();
$(
v.push($x);
)*
v
}
};
}
fnpää() {
antaa v = make_vector![1, 2, 3];
println!("{:?}", v); // tulostaa "[1, 2, 3]"
}
Ohjelma määrittelee a make_vector! makro, joka luo uuden vektorin pilkuilla eroteltujen lausekkeiden luettelosta pää toiminto.
Makron sisällä kuvion määritelmä vastaa makrolle välitettyjä argumentteja. The $( $x: expr ),* syntaksi vastaa kaikkia pilkuilla erotettuja lausekkeita, jotka tunnistetaan nimellä $x.
The $( ) laajennuskoodin syntaksi iteroituu jokaisen lausekkeen yli argumenttiluettelossa, joka välitetään makrolle sulkeva sulkumerkki, joka osoittaa, että iteraatioita tulisi jatkaa, kunnes makro käsittelee kaikki ilmaisuja.
Järjestä ruosteprojektisi tehokkaasti
Ruostemakrot parantavat koodin organisointia antamalla sinun määrittää uudelleenkäytettäviä koodimalleja ja abstraktioita. Makrot voivat auttaa sinua kirjoittamaan tiiviimpää, ilmeikkäämpää koodia ilman päällekkäisyyksiä projektin eri osissa.
Voit myös järjestää Rust-ohjelmat laatikoihin ja moduuleihin parantaaksesi koodin organisointia, uudelleenkäytettävyyttä ja yhteistoimintaa muiden laatikoiden ja moduulien kanssa.