CodeBlanks Logo Icon CodeBlanks

syn ve quote

syn ve quote crate'lerini kullanarak kod üretirsin.

syn ve quote

Prosedürel makro yazmanın iki temel aracı:

  • syn: TokenStream'i Rust sözdizimi ağacına (DeriveInput, ItemFn, Expr...) ayrıştırır.
  • quote: quote! { .. } içinde yazılan Rust kodunu, #değişken yerleştirmeleriyle birlikte yeniden TokenStream'e çevirir.
let ad = &ast.ident;                 // syn::Ident: Kisi
let n = alanlar.len();
let uretilen = quote! {
    impl #ad {
        fn alan_sayisi() -> usize { #n }
    }
};

Ara adımda kod bir metin değil, yapılandırılmış belirteçlerdir; bu sayede hata mesajları doğru kaynak konumunu gösterir.

Kod üretimini metinle görmek

quote!'in ürettiğini, aynı şablonu metinle kurarak görebiliriz; makro hata ayıklamasında cargo expand da tam olarak bunu gösterir:

fn impl_uret(ad: &str, alanlar: &[&str]) -> String {
    format!(
        "impl {ad} {{ fn alan_sayisi() -> usize {{ {} }} }}",
        alanlar.len()
    )
}

Gerçek makrolarda metin birleştirme yerine quote! kullanılır; metin yaklaşımı tırnak, kaçış ve konum bilgisi sorunlarına açıktır.

Uygulama Şablondan kod

Yukarıdaki impl_uret fonksiyonunu yaz. impl_uret("Kisi", &["ad", "yas"]) sonucunu yazdır.

Başlangıç kodu

main.rs
fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
fn impl_uret(ad: &str, alanlar: &[&str]) -> String {
    format!(
        "impl {ad} {{ fn alan_sayisi() -> usize {{ {} }} }}",
        alanlar.len()
    )
}

fn main() {
    println!("{}", impl_uret("Kisi", &["ad", "yas"]));
}

Beklenen çıktı

impl Kisi { fn alan_sayisi() -> usize { 2 } }

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Makroda kullanıcı hatası (örneğin enum'a uygulanmış struct makrosu) nasıl bildirilmeli?

  • syn::Error::new_spanned(..).to_compile_error() ile doğru konumda derleme hatası Doğru cevap
  • panic!
  • Sessizce boş çıktı
  • println!

Açıklama: panic de derleme hatası verir ama konumu belirsizdir; span'li hata kullanıcıyı doğru satıra götürür.

2 Değişken yerleştir

Soru
quote! {
    impl ____ad {
        fn alan_sayisi() -> usize { #n }
    }
}
Cevap
quote! {
    impl #ad {
        fn alan_sayisi() -> usize { #n }
    }
}

Açıklama: quote! içinde #ad, ad değişkenini koda yerleştirir.

3 Araç ve çıktısı

Kavram Anlamı
syn::parse_macro_input! Sözdizimi ağacı
quote! TokenStream
cargo expand Açılmış kod
syn::Error Konumlu hata

İleri seviye bölümündeki tüm dersler