CodeBlanks Logo Icon CodeBlanks

Monomorphization

Monomorphization ile generic'lerin maliyetini öğrenirsin.

Monomorphization

Generic bir fonksiyon her somut tür için ayrı ayrı derlenir. Her kopya o türe göre tamamen optimize edilir; bedeli kod şişmesi (code bloat) ve daha uzun derlemedir:

fn tanim<T: std::fmt::Debug>(x: T) -> String {
    format!("{x:?}")
}

tanim(5);          // tanim::<i32>
tanim("a");        // tanim::<&str>
tanim(vec![1, 2]); // tanim::<Vec<i32>>  → üç ayrı fonksiyon

Büyük bir generic fonksiyonda kod şişmesini azaltmanın yaygın yolu, türden bağımsız kısmı generic olmayan bir iç fonksiyona taşımaktır.

İç fonksiyon deseni

Generic giriş ince tutulur, asıl iş tek bir somut fonksiyonda yapılır:

pub fn oku<P: AsRef<std::path::Path>>(yol: P) -> std::io::Result<String> {
    fn ic(yol: &std::path::Path) -> std::io::Result<String> {
        // uzun, türden bağımsız gövde
        std::fs::read_to_string(yol)
    }
    ic(yol.as_ref())
}

Alternatif: sık çağrılmayan, büyük kod yollarında &dyn Trait kullanmak. cargo bloat aracı hangi fonksiyonların ikili dosyada en çok yer kapladığını gösterir.

Uygulama Üç kopya

Yukarıdaki generic tanim fonksiyonunu yaz. 5, "a" ve vec![1, 2] için sonuçları | ile ayırarak yazdır.

Başlangıç kodu

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

Örnek çözüm

main.rs
fn tanim<T: std::fmt::Debug>(x: T) -> String {
    format!("{x:?}")
}

fn main() {
    println!("{} | {} | {}", tanim(5), tanim("a"), tanim(vec![1, 2]));
}

Beklenen çıktı

5 | "a" | [1, 2]

Soru ve cevaplar

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

1 Standart kütüphanede <code>fs::read_to_string&lt;P: AsRef&lt;Path&gt;&gt;</code> neden içeride generic olmayan bir fonksiyon çağırır?

  • Hız için
  • Güvenlik için
  • Gelenek
  • Asıl işin her P türü için tekrar derlenmemesi için Doğru cevap

Açıklama: Dış generic katman yalnızca as_ref() çağırır; gövde tek bir kopyada kalır.

2 Ortak gövde

Soru
pub fn oku<P: AsRef<Path>>(yol: P) -> io::Result<String> {
    fn ic(yol: &Path) -> io::Result<String> { fs::read_to_string(yol) }
    ic(yol.____())
}
Cevap
pub fn oku<P: AsRef<Path>>(yol: P) -> io::Result<String> {
    fn ic(yol: &Path) -> io::Result<String> { fs::read_to_string(yol) }
    ic(yol.as_ref())
}

Açıklama: as_ref generic P'yi &Path'e çevirir; ic tek kez derlenir.

3 Çağrı ve üretilen kopya

Kavram Anlamı
tanim(5) tanim::<i32>
tanim("a") tanim::<&str>
tanim(vec![1, 2]) tanim::<Vec<i32>>
tanim(7) Yeni kopya yok (i32 var)

Uzman bölümündeki tüm dersler