CodeBlanks Logo Icon CodeBlanks

Deref

Deref trait'i ile otomatik referans çözümü öğrenirsin.

Deref

Deref trait'i, bir türün * operatörüne nasıl davranacağını belirler. Akıllı işaretçileri "içerdiği değer gibi" kullanmayı sağlayan budur:

use std::ops::Deref;

struct Sarici<T>(T);

impl<T> Deref for Sarici<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.0
    }
}

let s = Sarici(String::from("Ece"));
println!("{}", s.len());   // 3: String'in metodu

type Target, trait'in ilişkili türüdür: çözülünce hangi türün elde edileceğini söyler.

Zincirleme dönüşüm

Deref coercion zincirleme çalışır ve çalışma anı maliyeti yoktur:

fn selam(ad: &str) -> String {
    format!("Merhaba {ad}")
}

let s = Sarici(String::from("Ece"));
println!("{}", selam(&s));   // &Sarici<String> → &String → &str

Deref'i yalnızca akıllı işaretçi benzeri türler için uygula; sıradan bir struct'a eklemek kodda "gizli" davranışlar yaratır ve okunurluğu düşürür. Değiştirilebilir sürüm DerefMut'tur.

Uygulama Sarmalayıcı

Yukarıdaki Sarici<T> türüne Deref uygula ve fn selam(ad: &str) -> String yaz. Sarici(String::from("Ece")) için selam(&s) sonucunu ve s.len() değerini boşlukla yazdır.

Başlangıç kodu

main.rs
use std::ops::Deref;

fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
use std::ops::Deref;

struct Sarici<T>(T);

impl<T> Deref for Sarici<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.0
    }
}

fn selam(ad: &str) -> String {
    format!("Merhaba {ad}")
}

fn main() {
    let s = Sarici(String::from("Ece"));
    println!("{} {}", selam(&s), s.len());
}

Beklenen çıktı

Merhaba Ece 3

Soru ve cevaplar

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

1 Deref coercion ne yapar?

  • Yalnızca Box için çalışır
  • &Sarici<String> → &String → &str gibi referansları otomatik dönüştürür Doğru cevap
  • Değeri kopyalar
  • Sahipliği taşır

Açıklama: Derleyici beklenen türe ulaşana kadar deref zincirini ekler; bu yüzden &String alan yere &str bekleyen fonksiyon verilebilir.

2 İlişkili tür

Soru
impl<T> Deref for Sarici<T> {
    type ____ = T;
    fn deref(&self) -> &T {
        &self.0
    }
}
Cevap
impl<T> Deref for Sarici<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.0
    }
}

Açıklama: Deref trait'inin ilişkili türü Target'tır.

3 Tür ve Target

Kavram Anlamı
Box<T> T
String str
Vec<T> [T]
Rc<T> T (paylaşılan)

Orta seviye bölümündeki tüm dersler