CodeBlanks Logo Icon CodeBlanks

Özet - Bildirimsel makrolar

macro_rules! ve tekrarları birleştirerek bir vec_of! makrosu yazarsın.

Bildirimsel makrolar özeti

macro_rules! kalıp eşleme ile kod üretir. Fragmanlar (expr, ident, ty, tt...) neyin beklendiğini, tekrarlar ($(..),*, +, ?) kaç kez olduğunu söyler. Birden çok kol ve özyineleme mümkündür. Makrolar hijyeniktir; dışa açılırken #[macro_export] ve $crate:: kullanılır. Fonksiyon yetiyorsa fonksiyon yaz; makro değişken argüman, kod üretimi ve derleme anı denetim için.

Kendi vec! makron

Boş kullanım, tekrar ve sondaki virgülü destekleyen bir liste makrosu:

macro_rules! liste {
    () => {
        Vec::new()
    };
    ($($x:expr),+ $(,)?) => {{
        let mut v = Vec::new();
        $(v.push($x);)+
        v
    }};
}

Gerçek vec!, kapasiteyi önceden ayırmak için eleman sayısını derleme anında hesaplar.

Uygulama Liste makrosu

Yukarıdaki liste! makrosunu yaz. let a: Vec<i32> = liste![]; ve sondaki virgüllü let b = liste![1, 2, 3,]; değerlerini {:?} ile boşlukla yazdır.

Başlangıç kodu

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

Örnek çözüm

main.rs
macro_rules! liste {
    () => {
        Vec::new()
    };
    ($($x:expr),+ $(,)?) => {{
        let mut v = Vec::new();
        $(v.push($x);)+
        v
    }};
}

fn main() {
    let a: Vec<i32> = liste![];
    let b = liste![1, 2, 3,];
    println!("{:?} {:?}", a, b);
}

Beklenen çıktı

[] [1, 2, 3]

Soru ve cevaplar

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

1 <code>vec![0; 5]</code> ve <code>vec![1, 2]</code> aynı makroyla nasıl çalışır?

  • İkisi aynı kalıp
  • Çalışmaz
  • vec!'in iki ayrı kolu vardır: ($e:expr; $n:expr) ve ($($x:expr),*) Doğru cevap
  • Derleyici özel davranır

Açıklama: Makro kolları sırayla denenir; noktalı virgül ikinci kolun kalıbına uymaz.

2 Sondaki virgül

Soru
($($x:expr),+ ____) => {{
    let mut v = Vec::new();
    $(v.push($x);)+
    v
}};
Cevap
($($x:expr),+ $(,)?) => {{
    let mut v = Vec::new();
    $(v.push($x);)+
    v
}};

Açıklama: $(,)? isteğe bağlı tek bir virgülü kabul eder.

3 Grubun özeti

Kavram Anlamı
macro_rules! Kalıp ile kod üretir
$x:expr Fragman
$(..),* Tekrar
Hijyen Ad çakışması yok

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