&dyn Trait
- Rust kursu
- İleri seviye
- Ders 58/81
- 4 dk
&dyn Trait ile referans tabanlı dağıtım yaparsın.
&dyn Trait
Trait nesnesinin sahiplik gerektirmeyen biçimi ödünç &dyn Trait ve &mut dyn Trait'tir. Heap ayırması yoktur; generic'e göre avantajı, fonksiyonun tek bir kopyasının derlenmesidir. Standart kütüphane bunu G/Ç için sık kullanır:
use std::io::Write;
fn yaz(w: &mut dyn Write, mesaj: &str) -> std::io::Result<()> {
writeln!(w, "{mesaj}")
}
let mut tampon: Vec<u8> = Vec::new();
yaz(&mut tampon, "merhaba")?; // belleğe
yaz(&mut std::io::stdout(), "merhaba")?; // ekranaAynı fonksiyon dosya, soket ya da bellek tamponuyla çalışır.
Ömürlü trait nesneleri
Trait nesnelerinin de bir ömrü vardır. Box<dyn Trait> varsayılan olarak Box<dyn Trait + 'static>'tir; ödünç veri tutan bir türü kutulamak için ömrü açıkça yazmak gerekir:
struct Bakis<'a>(&'a str);
impl Ses for Bakis<'_> {
fn ses(&self) -> String { self.0.to_string() }
}
fn kutula<'a>(s: &'a str) -> Box<dyn Ses + 'a> {
Box::new(Bakis(s))
}Uygulama Hedeften bağımsız yazma
Yukarıdaki yaz fonksiyonunu yaz. Bir Vec<u8> tamponuna merhaba yaz; tamponu metne çevirip merhaba (8 bayt) biçiminde yazdır.
Başlangıç kodu
use std::io::{self, Write};
fn main() {
// buraya yaz
}Örnek çözüm
use std::io::{self, Write};
fn yaz(w: &mut dyn Write, mesaj: &str) -> io::Result<()> {
writeln!(w, "{mesaj}")
}
fn main() -> io::Result<()> {
let mut tampon: Vec<u8> = Vec::new();
yaz(&mut tampon, "merhaba")?;
let metin = String::from_utf8_lossy(&tampon);
println!("{} ({} bayt)", metin.trim(), tampon.len());
Ok(())
}Beklenen çıktı
merhaba (8 bayt)
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 <code>&dyn Write</code> yerine <code>&mut dyn Write</code> neden gerekir?
- Gerekmez
- Daha hızlıdır
- dyn ile & kullanılamaz
- Write::write_all &mut self alır; yazmak hedefi değiştirir Doğru cevap
Açıklama: Trait nesnesi de metotların self biçimine uymalıdır; &dyn yalnızca &self metotlarını çağırabilir.
2 Değiştirilebilir trait nesnesi
fn yaz(w: &____ dyn Write, mesaj: &str) -> std::io::Result<()> {
writeln!(w, "{mesaj}")
}
fn yaz(w: &mut dyn Write, mesaj: &str) -> std::io::Result<()> {
writeln!(w, "{mesaj}")
}
Açıklama: Write metotları &mut self aldığı için &mut dyn Write gerekir.
3 Biçim ve özelliği
| Kavram | Anlamı |
|---|---|
&dyn T |
Ödünç, salt okuma |
&mut dyn T |
Ödünç, değiştirir |
Box<dyn T> |
Sahip, 'static |
Box<dyn T + 'a> |
Ödünç veri tutabilir |