Monomorphization
- Rust kursu
- Uzman
- Ders 14/46
- 4 dk
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ı fonksiyonBü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
fn main() {
// buraya yaz
}Örnek çözüm
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<P: AsRef<Path>></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
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.____())
}
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) |