CodeBlanks Logo Icon CodeBlanks

Newtype pattern

Newtype pattern ile trait çakışmasını çözersin.

Newtype pattern

Yetim kuralı, başka crate'lerin trait'ini başka crate'lerin türüne uygulamayı yasaklar: impl Display for Vec<String> yazılamaz. Çözüm, türü tek alanlı kendi struct'ına sarmaktır; sarmalayıcı senin türün olduğu için uygulama serbesttir:

struct Liste(Vec<String>);

impl std::fmt::Display for Liste {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "[{}]", self.0.join(", "))
    }
}

Newtype çalışma anında hiçbir maliyet getirmez; bellekte içteki türle aynıdır.

Tür güvenliği için newtype

Aynı temel türe sahip ama anlamı farklı değerler karıştırılamaz hale gelir:

struct KullaniciId(u64);
struct SiparisId(u64);

fn siparis_bul(id: SiparisId) { .. }
// siparis_bul(KullaniciId(7));   // hata: tür uyuşmuyor

Doğrulama da kurucuya konabilir: Eposta::new(s) yalnızca geçerli adreslerde Some döndürürse, programın geri kalanı her Eposta'nın geçerli olduğuna güvenebilir.

Uygulama Yazdırılabilir liste

Yukarıdaki Liste newtype'ını ve Display uygulamasını yaz. Liste(vec!["elma".into(), "armut".into()]) değerini {} ile yazdır.

Başlangıç kodu

main.rs
use std::fmt;

fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
use std::fmt;

struct Liste(Vec<String>);

impl fmt::Display for Liste {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[{}]", self.0.join(", "))
    }
}

fn main() {
    let l = Liste(vec!["elma".into(), "armut".into()]);
    println!("{}", l);
}

Beklenen çıktı

[elma, armut]

Soru ve cevaplar

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

1 Newtype'ın dezavantajı nedir ve nasıl hafifletilir?

  • Yavaştır
  • Bellek harcar
  • Dezavantajı yok
  • İçteki türün metotları kaybolur; Deref uygulamak ya da gerekenleri yönlendirmek Doğru cevap

Açıklama: Deref her şeyi açar ve sarmalayıcının amacını zayıflatabilir; yalnızca gerekli metotları elle yönlendirmek daha kontrollüdür.

2 Sarmalayıcı

Soru
struct Liste____;

impl std::fmt::Display for Liste { .. }
Cevap
struct Liste(Vec<String>);

impl std::fmt::Display for Liste { .. }

Açıklama: Tek alanlı tuple struct, newtype desenidir.

3 Uygulama ve izin

Kavram Anlamı
impl Display for Vec<String> Yasak
impl Display for Liste İzinli
KullaniciId(u64) Tür güvenliği
size_of::<Liste>() Vec ile aynı

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