Rust'un tarihi ilkelerinden biri tür güvenliğini sağlamak ve çalıştırma hatalarına yol açabilecek örtük dönüşümleri önlemektir. Ancak kodun kullanım kolaylığı için, referanslarla, akıllı işaretçilerle çalışmayı basitleştirmek ve evrensel API'lara imkan tanımak amacıyla kısmi otomatik dönüşümler deref coercion ve From/Into trait'leri aracılığıyla gerçekleştirilmektedir.
Sorun, otomatik dönüşümlerin kafa karışıklığına yol açabileceği durumlarda ortaya çıkar; örneğin, bir &String'in &str bekleyen bir yere geçirildiğinde. Gizli Deref::deref çağrılır ve bazen beklenmedik sonuçlar doğabilir (örneğin, geçirilen parametrelerin tipi değiştiğinde). Ayrıca, as aracılığıyla doğrudan ve açık bir tür dönüştürmesi sorunu da vardır.
Çözüm: Rust, akıllı işaretçiler (Box, Rc, Arc) ve diziler (&String'den &str'ye, &Vec'den &slice'a) için derleyici seviyesinde sıkı deref-coercion kuralları uygular. Açık dönüşümler için, temel dönüşümler için From, Into, TryFrom, TryInto, as trait'leri sağlanmıştır. Hatalardan kaçınmaya yardımcı olan birbirinden bağımsız tür güvenliği ve örtük dönüşümlerin kısıtlanmasıdır.
Kod örneği:
fn print_text(text: &str) { println!("{}", text); } let s = String::from("Hello!"); print_text(&s); // s: String, &s: &String, otomatik dönüşüm &str'ye
Anahtar özellikler:
Kendi türleriniz için kendi Deref'ini uyguladığınızda deref coercion çalışır mı?
Evet, kendi türünüz için Deref trait'ini uygularsanız, derleyici, örneğin, sarmalayıcınızı beklenen ilgili referans türü için işlev imzası içinde otomatik olarak dönüştürebilir.
Deref coercion, değerler için mi yoksa referanslar için mi gerçekleşir?
Hayır, otomatik dereferanslama yalnızca referansların geçişinde gerçekleşir ve yalnızca tür Deref'i uyguladığında olur.
As ile sayılar ve enum üzerinde tür dönüşümünün hangi kısıtlamaları vardır?
as güvenliği garanti etmez: sayılar arasında dönüşüm, taşma veya veri kaybına yol açabilir ve enum için anlamlı olmayan değerlerle sonuçlanabilir (örneğin, geçersiz enum varyantına dönüşüm).
Yeni bir programcı, &String kabul eden bir işlev yazıyor ve doğrudan &str kullanamıyor, her yerde string'den text.to_string() yapıyor. Bu bellek ve performans açısından israf.
Artıları:
Eksileri:
İşlev &str türünde bir argüman alır, bu nedenle dereferanslama veya dönüştürme destekleyen her tür ile çağrılabilir: &str, &String, string literalleri. Gereksiz tahsisler gerektirmez.
Artıları:
Eksileri: