derive macro
- Rust kursu
- İleri seviye
- Ders 80/81
- 7 dk
Özel bir derive makrosu yazıp test edersin.
Bitirme görevi: derive makrosu
Kendi #[derive(Tanimla)] makronun üreteceği kodu tasarla: struct'ın adını ve her alanı Display ile yazan bir tanim() metodu. Gerçek makroda syn ile alanlar okunur ve quote! ile şu üretilir:
impl Kisi {
fn tanim(&self) -> String {
let mut s = String::from("Kisi { ");
s.push_str(&format!("ad: {}", self.ad));
s.push_str(", ");
s.push_str(&format!("yas: {}", self.yas));
s.push_str(" }");
s
}
}Alıştırmada struct tanımını alan bir macro_rules! ile aynı kodu üreteceğiz.
macro_rules! ile üretim
Tekrar kalıbı her alan için bir parça üretir; join ayraçları yerleştirir:
macro_rules! tanimlanir {
(struct $ad:ident { $($alan:ident : $tur:ty),* $(,)? }) => {
struct $ad { $($alan: $tur),* }
impl $ad {
fn tanim(&self) -> String {
let parcalar: Vec<String> = vec![
$(format!("{}: {}", stringify!($alan), self.$alan)),*
];
format!("{} {{ {} }}", stringify!($ad), parcalar.join(", "))
}
}
};
}self.$alan, makro değişkeniyle alan erişimi üretir.
Uygulama Tanımlanabilir struct
Yukarıdaki tanimlanir! makrosunu yaz ve struct Kisi { ad: String, yas: u32 } tanımını onunla üret. Kisi { ad: "Ece".into(), yas: 30 }.tanim() sonucunu yazdır.
Başlangıç kodu
fn main() {
// buraya yaz
}Örnek çözüm
macro_rules! tanimlanir {
(struct $ad:ident { $($alan:ident : $tur:ty),* $(,)? }) => {
struct $ad {
$($alan: $tur),*
}
impl $ad {
fn tanim(&self) -> String {
let parcalar: Vec<String> = vec![
$(format!("{}: {}", stringify!($alan), self.$alan)),*
];
format!("{} {{ {} }}", stringify!($ad), parcalar.join(", "))
}
}
};
}
tanimlanir!(struct Kisi { ad: String, yas: u32 });
fn main() {
let k = Kisi { ad: "Ece".into(), yas: 30 };
println!("{}", k.tanim());
}Beklenen çıktı
Kisi { ad: Ece, yas: 30 }
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Alanlar arasındaki virgülü doğru koymanın en kolay yolu nedir?
- Her alandan sonra virgül yazıp sonuncuyu silmek
- Virgül kullanmamak
- Makroda mümkün değil
- Parçaları bir Vec<String>'e toplayıp join(", ") ile birleştirmek Doğru cevap
Açıklama: join, ayraç sorununu sıfır ve tek eleman durumları dahil doğru çözer.
2 Alan erişimi üret
$(format!("{}: {}", stringify!($alan), self.____)),*
$(format!("{}: {}", stringify!($alan), self.$alan)),*
Açıklama: self.$alan her alan için ayrı bir erişim üretir.
3 Parça ve rolü
| Kavram | Anlamı |
|---|---|
stringify!($ad) |
Struct adı |
stringify!($alan) |
Alan adı |
self.$alan |
Alan değeri |
join(", ") |
Ayraçlar |