Özet - Bildirimsel makrolar
- Rust kursu
- İleri seviye
- Ders 47/81
- 5 dk
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
fn main() {
// buraya yaz
}Örnek çözüm
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
($($x:expr),+ ____) => {{
let mut v = Vec::new();
$(v.push($x);)+
v
}};
($($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 |