Rust
derive macro
Ö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.
Örnek çözümü göster
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());
}
Kendini test et
-
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
Cevabı göster
Parçaları bir Vec<String>'e toplayıp join(", ") ile birleştirmek — join, ayraç sorununu sıfır ve tek eleman durumları dahil doğru çözer.
-
Alan erişimi üret
$(format!("{}: {}", stringify!($alan), self.____)),*
Cevabı göster
$(format!("{}: {}", stringify!($alan), self.$alan)),*
-
Parça ve rolü
- stringify!($ad)
- Struct adı
- stringify!($alan)
- Alan adı
- self.$alan
- Alan değeri
- join(", ")
- Ayraçlar
Sıradaki ders: FFI wrapper