attribute makrosu
- Rust kursu
- İleri seviye
- Ders 50/81
- 4 dk
#[proc_macro_attribute] ile attribute makrosu yazarsın.
attribute makrosu
Öznitelik makroları, işaretlendikleri öğenin tamamını alır ve yerine istediklerini koyar. Ayrıca özniteliğin kendi argümanlarını da alırlar:
#[proc_macro_attribute]
pub fn olcumle(arg: TokenStream, oge: TokenStream) -> TokenStream {
let mut f = syn::parse_macro_input!(oge as syn::ItemFn);
let ad = f.sig.ident.to_string();
let govde = &f.block;
f.block = syn::parse_quote!({
println!("{} çağrıldı", #ad);
#govde
});
quote::quote!(#f).into()
}
// kullanım:
#[olcumle]
fn kare(x: i32) -> i32 { x * x }#[tokio::main], #[test] benzeri ve web çatılarındaki #[get("/")] öznitelik makrolarıdır.
macro_rules! ile sarmak
Aynı dönüşümü, fonksiyonu makroya argüman olarak vererek macro_rules! ile de yapabiliriz:
macro_rules! olcumle {
(fn $ad:ident($($arg:ident : $tur:ty),*) -> $don:ty $govde:block) => {
fn $ad($($arg: $tur),*) -> $don {
println!("{} çağrıldı", stringify!($ad));
$govde
}
};
}
olcumle! {
fn kare(x: i32) -> i32 { x * x }
}$govde:block süslü parantezli gövdeyi tek parça olarak yakalar.
Uygulama Çağrıyı bildir
Yukarıdaki olcumle! makrosunu yaz ve fn kare(x: i32) -> i32 { x * x } fonksiyonunu onunla tanımla. main'de kare(4) sonucunu yazdır.
Başlangıç kodu
fn main() {
// buraya yaz
}Örnek çözüm
macro_rules! olcumle {
(fn $ad:ident($($arg:ident : $tur:ty),*) -> $don:ty $govde:block) => {
fn $ad($($arg: $tur),*) -> $don {
println!("{} çağrıldı", stringify!($ad));
$govde
}
};
}
olcumle! {
fn kare(x: i32) -> i32 {
x * x
}
}
fn main() {
let s = kare(4);
println!("{}", s);
}Beklenen çıktı
kare çağrıldı 16
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Öznitelik makrosu fonksiyonu alır ama çıktıya hiç koymazsa ne olur?
- Uyarı verir
- Fonksiyon programdan kaybolur Doğru cevap
- Derleyici geri ekler
- Panic
Açıklama: Öznitelik makrosu öğeyi tamamen değiştirir; özgün öğeyi korumak makronun sorumluluğudur.
2 Gövdeyi yakala
(fn $ad:ident($($arg:ident : $tur:ty),*) -> $don:ty $govde:____) => { .. }
(fn $ad:ident($($arg:ident : $tur:ty),*) -> $don:ty $govde:block) => { .. }
Açıklama: block fragmanı süslü parantezli bir bloğu eşler.
3 Öznitelik ve rolü
| Kavram | Anlamı |
|---|---|
#[proc_macro_attribute] |
Öznitelik makrosu tanımı |
arg: TokenStream |
Öznitelik argümanları |
oge: TokenStream |
İşaretlenen öğe |
syn::ItemFn |
Fonksiyon ağacı |