CodeBlanks Logo Icon CodeBlanks

dyn Trait

dyn Trait ile dinamik dağıtım yapmayı öğrenirsin.

dyn Trait

Bir trait nesnesi (&dyn Ses, Box<dyn Ses>) şişman işaretçidir: veri adresi ve bir vtable adresi. Vtable, o somut tür için trait metotlarının adreslerini, türün boyutunu, hizalamasını ve drop fonksiyonunu tutan derleyicinin ürettiği bir tablodur:

use std::mem::size_of;

println!("{}", size_of::<&Kedi>());      // 8: tek işaretçi
println!("{}", size_of::<&dyn Ses>());   // 16: veri + vtable

x.ses() çağrısı, vtable'dan metodun adresini okuyup oraya atlar: tek bir dolaylı çağrı.

Neden şişman?

Somut tür derleme anında bilinmediği için metot adresleri ve boyut çalışma anında gereklidir. Dilimler de şişman işaretçidir (&[T] = adres + uzunluk); dyn Trait ve [T] gibi boyutu bilinmeyen türlere DST (dynamically sized type) denir ve yalnızca işaretçi arkasında kullanılabilirler.

println!("{}", size_of::<&[u8]>());   // 16: adres + uzunluk
println!("{}", size_of::<&str>());    // 16
// let x: dyn Ses;                     // hata: boyutu bilinmiyor

Uygulama İşaretçi boyutları

Ses trait'ini ve Kedi türünü yaz. size_of::<&Kedi>() ve size_of::<&dyn Ses>() değerlerini boşlukla yazdır (64 bit sistem).

Başlangıç kodu

main.rs
use std::mem::size_of;

fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
use std::mem::size_of;

trait Ses {
    fn ses(&self) -> String;
}

struct Kedi;

impl Ses for Kedi {
    fn ses(&self) -> String {
        String::from("Miyav")
    }
}

fn main() {
    println!("{} {}", size_of::<&Kedi>(), size_of::<&dyn Ses>());
}

Beklenen çıktı

8 16

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Aynı somut tür için kaç vtable oluşturulur?

  • Her nesne için bir tane
  • Hiç
  • Çalışma anında üretilir
  • Her (tür, trait) çifti için bir tane, tüm nesneler paylaşır Doğru cevap

Açıklama: Vtable statik bellekte durur; trait nesnesi yalnızca ona bir işaretçi taşır.

2 Trait nesnesi referansı

Soru
let s: &____ Ses = &Kedi;
println!("{}", s.ses());
Cevap
let s: &dyn Ses = &Kedi;
println!("{}", s.ses());

Açıklama: &dyn Ses, Ses uygulayan herhangi bir türe şişman işaretçidir.

3 Tür ve boyutu (64 bit)

Kavram Anlamı
&Kedi 8
&dyn Ses 16
&[u8] 16 (adres + uzunluk)
Box<dyn Ses> 16 (veri + vtable)

İleri seviye bölümündeki tüm dersler