irfo
Moderatör
- Katılım
- 7 Ocak 2026
- Mesajlar
- 290
- Tepkime puanı
- 2
- Puanları
- 18
Rust öğrenmeye başladığınızda karşınıza çıkan en kafa karıştırıcı konulardan biri, metinleri temsil etmek için neden iki farklı yapı (
Bu iki yapı arasındaki farkı anlamak, sadece kodun derlenmesini sağlamakla kalmaz, aynı zamanda programınızın performansını da doğrudan etkiler.
Neden? Çünkü &str parametresi alan bir fonksiyona hem &str tipindeki verileri hem de String referanslarını gönderebilirsiniz (Deref Coercion sayesinde). Bu, fonksiyonunuzu daha esnek kılar.
String ve &str) olduğudur. Bu ayrım, Rust’ın bellek yönetimi (sahiplik ve ödünç alma) felsefesinin doğrudan bir sonucudur.Bu iki yapı arasındaki farkı anlamak, sadece kodun derlenmesini sağlamakla kalmaz, aynı zamanda programınızın performansını da doğrudan etkiler.
1. String: Sahipli, Dinamik ve Büyütülebilir
String tipi, Rust'ta "sahibi olduğunuz" (owned) metin verisidir. Veri, belleğin Heap (Öbek) kısmında saklanır.- Dinamiktir: Çalışma zamanında içeriği değiştirilebilir veya boyutu artırılabilir.
- Sahiplik:
Stringkapsam dışına çıktığında, tuttuğu bellek alanı otomatik olarak temizlenir. - Kullanım: Kullanıcıdan girdi alırken veya bir metni manipüle etmeniz (ekleme, çıkarma) gerektiğinde tercih edilir.
Kod:
let mut s = String::from("Merhaba"); s.push_str(" Dünya"); // Metin değiştirilebilir println!("{}", s);
2. &str: Ödünç Alınmış, Sabit ve Bir "Slice"
&str (string slice olarak okunur), bir metin verisinin belirli bir bölümüne veya tamamına verilen referanstır. Verinin sahibi değildir, sadece ona "bakar".- Sabittir: İçeriği değiştirilemez (immutable).
- Bellek Konumu: Genellikle belleğin Stack (Yığın) kısmında veya ikili dosyanın (binary) veri bölümünde (string literals) bulunur.
- Hafiftir: Sadece verinin başladığı adresi ve uzunluğunu tutan bir göstergedir.
Kod:
let mesaj: &str = "Selam"; // Bu bir 'string literal'dır ve tipi &str'dir. // mesaj.push_str("!"); // HATA: &str değiştirilemez.
3. Bellek Yapısı: Stack vs Heap
Aralarındaki en büyük fark bellekte nasıl temsil edildikleridir.String, Heap'teki veriyi yöneten bir yapı iken; &str, o veriye erişim sağlayan bir penceredir.| Özellik | String | &str |
| Bellek Konumu | Heap (Öbek) | Stack/Binary (İşaret ettiği yer Heap olabilir) |
| Sahiplik | Var (Sahibidir) | Yok (Ödünç almıştır) |
| Boyut Değişimi | Evet (Büyüyebilir) | Hayır (Sabittir) |
| Veri Yapısı | Pointer + Uzunluk + Kapasite | Pointer + Uzunluk |
4. Dönüşümler (Conversion)
İki tip arasında geçiş yapmak oldukça basittir ancak maliyetlerini bilmek gerekir:- &str -> String: to_string() veya String::from() kullanılır. Bu işlem Heap'te yeni bir alan ayırdığı için (allocation) bir maliyeti vardır.
- String -> &str: & operatörü veya .as_str() kullanılır. Bu işlem çok hızlıdır çünkü yeni bir veri oluşturmaz, sadece bir referans verir.
Kod:
let s_dilimi: &str = "Rust";let s_string: String = s_dilimi.to_string(); // &str'den String'e
let geri_dilim: &str = &s_string; // String'den &str'ye (Dereffing)
5. Fonksiyon Parametrelerinde Hangisini Kullanmalı?
Rust topluluğunun altın kuralı şudur: Eğer fonksiyonunuz metni değiştirmeyecekse, parametre olarak &str kullanın.Neden? Çünkü &str parametresi alan bir fonksiyona hem &str tipindeki verileri hem de String referanslarını gönderebilirsiniz (Deref Coercion sayesinde). Bu, fonksiyonunuzu daha esnek kılar.
Kod:
fn selamla(isim: &str) {println!("Merhaba, {}!", isim);}
fn main() {let s = String::from("Ali");selamla("Veli"); // &str ile çalışırselamla(&s); // String referansı ile de çalışır!}
Özet
- String bir kutu gibidir; içindeki metni siz yönetirsiniz, değiştirebilirsiniz ve çöpe atabilirsiniz.
- &str ise bir cam gibidir; kutunun içindeki metni görmenizi sağlar ama ona dokunamaz veya kutunun boyutunu değiştiremezsiniz.