Soru tarihi:
Yerel dillerle (C/C++) kıyaslandığında, Rust, referans (&str) ve sahiplik (String) türleri arasında kesin bir ayrım yaparak güvenli dize işlemleri sağlar. Bu, bellek hataları, tampon aşımı ve double-free ile ilgili çoğu hatadan kurtulmanızı sağlar.
Sorun:
Yetişkin GC dillerinin aksine, herhangi bir dizenin yönetilen bellek içinde yaşadığı Rust’ta, dizenin kim tarafından sahiplenildiğini, ne kadar süreyle yaşadığını ve değişikliklerden sonra dangling reference elde etmemek için nasıl davranıldığını net bir şekilde anlamak gerekir. UTF-8 dizeleriyle çalışma, indeksleme ve değişiklik yaparken dikkat gerektirir.
Çözüm:
Rust'ta String, içeriğine sahip olan değiştirilebilir ve heap üzerinde tahsis edilmiş bir dizidir. &str, UTF-8 garantisi olan bir bayt dizisine değişmez bir referanstır. Gerekirse, bu türler arasında güvenli dönüşüm yapmak mümkündür (&str -> String ve geri) std yöntemleri ile.
Kod örneği:
fn main() { let owned: String = String::from("Rust"); let borrowed: &str = &owned; let primitive: &str = "Hello"; // literal her zaman &str // Dönüşüm &str -> String let s: String = primitive.to_string(); // Dönüşüm String -> &str let st: &str = &s; println!("{} {} {} {}", owned, borrowed, primitive, st); }
Temel özellikler:
&'static str tipine sahiptir, String değilNeden dizeyi s[1] veya s[i] şeklinde indeksleyemeyiz?
Rust dizeleri UTF-8’dır, bu nedenle indeksleme doğrudan mevcut değildir: s[i] i’nci karakteri döndürmez ve bazen de hatalı bayt sınırına erişim nedeniyle panic ile sonuçlanır. Bunun yerine, .chars().nth(i) veya .get(start..end) yöntemlerini kullanın.
&str'yi güvenli bir şekilde değiştirmek mümkün mü?
Mümkün değil — &str her zaman immutable slice'dır. Değişiklikler için to_owned/to_string yapın veya String/Vec<u8> kullanın.
String::from("abc") ile "abc".to_string() arasında prensipte nasıl bir fark vardır?
Bu seçenekler sonuç olarak eşdeğerdir, her ikisi de &str'den veri kopyalayarak bir String oluşturur. Fark yalnızca tarzda: örneğin, to_string ToString trait'i üzerinden gerçekleştirilmiştir, String::from ise "sahiplik oluştur" ifadelerini daha belirgin şekilde ifade eder.
Fonksiyon bir String alıyordu ve içeride gereksiz bir dize kopyalaması (clone) yapıyordu, ardından başka bir fonksiyonda slice yazıyordu, kaynak nesnenin yaşam süresini uzatmayı unutarak. Sonuç: dangling reference & çökme.
Artılar:
Eksiler:
Fonksiyon &str alır, eğer değişiklik gerekiyorsa - içeride .to_string() çağrısında bulunur, dışarıda tüm mantık "zero copy" olarak kalır. Yaşam süreleri kontrol altındadır, bir tane bile gereksiz tahsis yoktur.
Artılar:
Eksiler: