CodeBlanks Logo Icon CodeBlanks

Object safety

Nesne güvenliği (object safety) kurallarını öğrenirsin.

Object safety

Bir trait'in dyn ile kullanılabilmesi için dyn uyumlu (eski adıyla object safe) olması gerekir. Engelleyen durumlar: Self döndüren metotlar, generic tür parametresi alan metotlar, self almayan ilişkili fonksiyonlar ve Sized üst trait'i. Çünkü vtable'da somut türü bilmeden bu metotlar çağrılamaz:

trait Kopyalanir {
    fn kopya(&self) -> Self;           // Self döner: dyn uyumsuz
}
// let x: Box<dyn Kopyalanir>;          // E0038

Bu yüzden Clone trait nesnesi olarak kullanılamaz.

where Self: Sized

Trait'in geri kalanını dyn ile kullanmaya devam etmek için sorunlu metodu ayır:

trait Sekil {
    fn alan(&self) -> f64;
    fn kopya(&self) -> Self
    where
        Self: Sized;
}

let k = Kare(3.0);
let k2 = k.kopya();                         // somut türde çalışır
let d: Box<dyn Sekil> = Box::new(k2);       // dyn de mümkün
// d.kopya();                               // dyn üzerinden çağrılamaz

Kutulu kopya için yaygın çözüm ayrı bir metottur: fn kutulu_kopya(&self) -> Box<dyn Sekil>.

Uygulama Uyumlu şekil trait'i

Yukarıdaki Sekil trait'ini yaz ve #[derive(Clone)] struct Kare(f64); için uygula (kopya = self.clone()). Kare(3.0).kopya() alanını ve onu Box<dyn Sekil> içine koyup dyn üzerinden alanını boşlukla yazdır.

Başlangıç kodu

main.rs
fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
trait Sekil {
    fn alan(&self) -> f64;
    fn kopya(&self) -> Self
    where
        Self: Sized;
}

#[derive(Clone)]
struct Kare(f64);

impl Sekil for Kare {
    fn alan(&self) -> f64 {
        self.0 * self.0
    }
    fn kopya(&self) -> Self {
        self.clone()
    }
}

fn main() {
    let k2 = Kare(3.0).kopya();
    let a = k2.alan();
    let d: Box<dyn Sekil> = Box::new(k2);
    println!("{} {}", a, d.alan());
}

Beklenen çıktı

9 9

Soru ve cevaplar

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

1 Bir trait'te dyn uyumsuz tek bir metot varsa ne yapılabilir?

  • O metoda where Self: Sized ekleyip trait nesnelerinden hariç tutmak Doğru cevap
  • Trait'i silmek
  • unsafe kullanmak
  • Hiçbir şey

Açıklama: Böyle işaretlenmiş metot somut türlerde çağrılabilir, dyn üzerinden çağrılamaz; trait dyn uyumlu kalır.

2 dyn'den hariç tut

Soru
fn kopya(&self) -> Self
where
    Self: ____;
Cevap
fn kopya(&self) -> Self
where
    Self: Sized;

Açıklama: where Self: Sized metodu trait nesnelerinden hariç tutar.

3 Metot ve dyn uyumu

Kavram Anlamı
fn alan(&self) -> f64 Uyumlu
fn kopya(&self) -> Self Uyumsuz
fn f<T>(&self, x: T) Uyumsuz (generic)
.. where Self: Sized Hariç tutulur

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