macro_rules!
- Rust kursu
- İleri seviye
- Ders 42/81
- 4 dk
macro_rules! ile makro tanımlamayı öğrenirsin.
macro_rules!
Bildirimsel makrolar, kod üreten kalıp eşleyicilerdir. Fonksiyonlardan farkları: derleme anında açılırlar, değişken sayıda argüman alabilirler ve ifade, tür ya da öğe gibi kod parçalarıyla çalışırlar:
macro_rules! kare {
($x:expr) => {
($x) * ($x)
};
}
let a = kare!(4); // (4) * (4)
let b = kare!(1 + 2); // (1 + 2) * (1 + 2) = 9$x:expr bir fragmandır: "x adlı bir ifade". Gövdedeki parantezler önemlidir; olmasaydı kare!(1 + 2) 1 + 2 * 1 + 2 = 5 olurdu.
Makro mu, fonksiyon mu?
Bir fonksiyon iş görüyorsa fonksiyon yaz: tür denetimi, belgelenmesi ve hata mesajları daha iyidir. Makro şu durumlarda gerekir: değişken sayıda argüman (println!, vec!), tekrarlayan kod üretmek (birçok tür için aynı impl), ya da derleme anında kod parçası üzerinde çalışmak (stringify!, assert_eq!'in mesajı).
// cargo expand: makronun açılmış halini gösterir
// $ cargo install cargo-expand && cargo expandUygulama İlk makro
Yukarıdaki kare! makrosunu parantezli gövdeyle yaz. kare!(4) ve kare!(1 + 2) sonuçlarını boşlukla yazdır.
Başlangıç kodu
fn main() {
// buraya yaz
}Örnek çözüm
macro_rules! kare {
($x:expr) => {
($x) * ($x)
};
}
fn main() {
println!("{} {}", kare!(4), kare!(1 + 2));
}Beklenen çıktı
16 9
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Makroyu çağırmadan önce tanımlamak neden gerekir?
- Gerekmez
- Derleyici yavaş olduğu için
- Yalnızca testlerde
- macro_rules! makroları kaynak sırasıyla görünür hale gelir Doğru cevap
Açıklama: Başka modüllerden kullanmak için #[macro_export] ya da modül sırası gerekir; fonksiyonlarda böyle bir kısıt yoktur.
2 İfade fragmanı
macro_rules! kare {
($x:____) => {
($x) * ($x)
};
}
macro_rules! kare {
($x:expr) => {
($x) * ($x)
};
}
Açıklama: expr fragmanı bir Rust ifadesini eşler.
3 Çağrı ve sonuç
| Kavram | Anlamı |
|---|---|
kare!(4) |
16 |
kare!(1 + 2) |
9 |
kare!(-3) |
9 (eksi) |
Parantezsiz $x * $x ile kare!(1 + 2) |
5 |