CodeBlanks Logo Icon CodeBlanks

Makro hygieni

Makro hijyeni (hygiene) kavramını öğrenirsin.

Makro hijyeni

Rust makroları hijyeniktir: makronun içinde tanımlanan yerel değişkenler, çağıran koddaki aynı adlı değişkenlerle karışmaz. Her tanımlayıcı geldiği "bağlamı" hatırlar:

macro_rules! ikile {
    ($x:expr) => {{
        let gecici = $x;
        gecici * 2
    }};
}

let gecici = 5;
let s = ikile!(gecici + 1);   // dıştaki gecici kullanılır: 12
println!("{s} {gecici}");    // 12 5

C'nin önişlemci makroları metin değiştirmesi yapar ve bu tür ad çakışmalarına açıktır; Rust'ta bu hata sınıfı yoktur.

Hijyenin sınırları

Hijyen yerel değişkenler ve etiketler için geçerlidir; fonksiyonlar, türler ve modül yolları için değildir. Makro başka bir modülde kullanılacaksa yolları $crate:: ile tam yazmak gerekir:

#[macro_export]
macro_rules! hata {
    ($m:expr) => {
        $crate::kayit::yaz("HATA", $m)   // makronun crate'inden
    };
}

Çağıranın bir değişkenini bilerek kullanmak isteyen makro, adı argüman olarak ($ad:ident) almalıdır.

Uygulama Hijyenik makro

Yukarıdaki ikile! makrosunu yaz. let gecici = 5; tanımladıktan sonra ikile!(gecici + 1) sonucunu ve gecici değerini boşlukla yazdır.

Başlangıç kodu

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

Örnek çözüm

main.rs
macro_rules! ikile {
    ($x:expr) => {{
        let gecici = $x;
        gecici * 2
    }};
}

fn main() {
    let gecici = 5;
    let s = ikile!(gecici + 1);
    println!("{} {}", s, gecici);
}

Beklenen çıktı

12 5

Soru ve cevaplar

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

1 Gövdedeki çift süslü parantez <code>{{ .. }}</code> ne işe yarar?

  • Dıştaki makro gövdesini, içteki ise bir blok ifadesini açar Doğru cevap
  • Kaçış karakteridir
  • Hata verir
  • Bir anlamı yok

Açıklama: İç blok, makronun birden çok deyimi tek bir ifade olarak döndürmesini sağlar.

2 Crate yolu

Soru
#[macro_export]
macro_rules! hata {
    ($m:expr) => {
        ____::kayit::yaz("HATA", $m)
    };
}
Cevap
#[macro_export]
macro_rules! hata {
    ($m:expr) => {
        $crate::kayit::yaz("HATA", $m)
    };
}

Açıklama: $crate, makronun tanımlandığı crate'in köküne genişler.

3 Kavram ve anlamı

Kavram Anlamı
Hijyen Yerel adlar karışmaz
{{ .. }} Blok ifadesi döndürür
$crate:: Makronun crate'i
#[macro_export] Crate dışına açar

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