LuvyAI — Ücretsiz başla. 18+

🚀 BAŞTAN SONA RUST DİLİ BÖLÜM-4: Ownership (Sahiplik Sistemi) ve Bellek Yönetimi 👑

Konu Özeti

Rust programlama dilinin bellek yönetimini diğer dillerden ayıran Ownership (Sahiplik) sistemi detaylandırılıyor. Stack ve heap bellek yapıları, ownership'in üç temel kuralı, String tipi ile dinamik bellek tahsisi ve move (taşıma) mekanizması örneklerle açıklanıyor. Değerlerin sahiplik kurallarına göre nasıl yönetildiği ve kapsam dışına çıktığında otomatik olarak bellekten temizlendiği vurgulanıyor.

🚀 BAŞTAN SONA RUST DİLİ BÖLÜM-4: Ownership (Sahiplik Sistemi) ve Bellek Yönetimi 👑

Selamlar! Serimizin 4. ve belki de EN KRİTİK bölümüne hoş geldiniz.

Bu bölümde, Rust'ı C++, Java, Go veya Python gibi dillerden tamamen ayıran, ona benzersiz hızını ve bellek güvenliğini veren ana mekanizmayı inceleyeceğiz: Ownership (Sahiplik Sistemi).

---

🧠 1. Stack ve Heap Bellek Mantığı 📚

Ownership konusuna girmeden önce bellek yapısını hatırlamalıyız:

• Stack (Yığın):
- LIFO (Last In, First Out) mantığıyla çalışır.
- Hızlıdır çünkü verilerin boyutu derleme zamanında (compile-time) sabittir ve bilinir.
- Örnek: `i32`, `bool`, `char`, sabit boyutlu array'ler.

• Heap (Yığın/Öbek):
- Boyutu derleme zamanında bilinmeyen veya çalışma zamanında değişebilen veriler için kullanılır.
- Yavaştır; işletim sistemi boş yer arar, adresi (pointer) döner.
- Örnek: Dinamik metinler (`String`), vektörler (`Vec`).

---

📜 2. Ownership'in 3 Altın Kuralı 🏆

Rust bellek yönetimini bir Garbage Collector (Çöp Toplayıcı) veya manuel `free()` / `delete()` işlemleriyle yapmaz. Bunun yerine 3 temel kural uygular:

1. Rust'taki her değerin bir sahibi (owner) vardır ve bu bir değişkendir.
2. Aynı anda yalnızca TEK BİR sahibi olabilir.
3. Sahibi olduğu değişken kapsama alanından (scope) çıktığında, değer otomatik olarak bellekten silinir (drop edilir).

{
let s = "selam"; // s geçerli

// s ile işlemler yapılır
}
// Bu parantez kapandığı an s scope dışına çıkar ve bellek anında temizlenir!

---

🧵 3. String Tipi ve Bellek Tahsisi 🔤

Bölüm 2'de gördüğümüz metin sabitleri (`&str`) immutable'dır ve doğrudan programa hardcode edilir. Ancak kullanıcıdan veri alırken boyutu dinamik olan `String` tipini kullanırız.

fn main() {
let mut s = String::from("Merhaba");
s.push_str(", Forum!"); // Metne ekleme yapıyoruz
println!("{}", s);
}

`String::from` kullanıldığında bellek isteği Heap'ten yapılır.

---

🔄 4. Move (Taşıma) Mantığı 📦

Aşağıdaki basit integer koduna bakalım:

let x = 5;
let y = x; // x'in değeri y'ye kopyalandı. Hem x hem y geçerli!

Çünkü `5` sabit boyutludur ve Stack'tedir (Copy trait'ine sahiptir).

Peki aynı şeyi Heap'te tutulan bir `String` ile yaparsak ne olur?

let s1 = String::from("Rust");
let s2 = s1; // Ne oldu?

println!("{}", s1); // <-- HATA! Derleyici geçit vermez!

#### Neden Hata Veriyor?
`s1` değişkeni Heap'teki verinin pointer'ını, uzunluğunu (len) ve kapasitesini (capacity) tutar. `let s2 = s1;` dediğimizde Rust veriyi Heap'te kopyalamaz (bu çok maliyetli olurdu).

Sadece pointer'ı `s2`'ye aktarır. Ancak iki değişken aynı Heap verisini gösterirse, scope bittiğinde iki kez temizleme (double free error) hatası oluşur!

Bu yüzden Rust, `s1`'i geçersiz kılar. Bu işleme **Move (Taşıma)** denir. Veri `s1`'den `s2`'ye taşınmıştır!

---

📋 5. Clone (Derin Kopyalama) 👯

Eğer Heap'teki veriyi gerçekten kopyalamak (deep copy) istiyorsak `clone` metodunu kullanırız:

fn main() {
let s1 = String::from("Rust");
let s2 = s1.clone(); // Heap'teki veri de kopyalandı

println!("s1 = {}, s2 = {}", s1, s2); // İkisi de sorunsuz çalışır!
}

---

⚙️ 6. Fonksiyonlar ve Ownership 🛠️

Bir değişkeni fonksiyona parametre olarak gönderdiğinizde, tıpkı değişken atamasındaki gibi Ownership fonksiyona **taşınır (move edilir)**!

fn main() {
let s = String::from("Geliştirici");

sahipligi_al(s);

// println!("{}", s); // HATA! s artık geçerli değil, sahipliği fonksiyona gitti.

let x = 10;
sayi_al(x);
// println!("{}", x); // GEÇERLİ! Tam sayılar Copy trait'ine sahip olduğu için taşınmaz, kopyalanır.
}

fn sahipligi_al(metin: String) {
println!("{}", metin);
} // metin scope dışına çıktı ve bellekten silindi!

fn sayi_al(sayi: i32) {
println!("{}", sayi);
}

---

📝 Bölüm Özeti ve Gelecek Bölüm 🔮

Ownership mantığı ilk başta kafa karıştırıcı gelebilir ama bellek sızıntılarını (memory leak) ve pointer hatalarını tamamen ortadan kaldıran muazzam bir sistemdir.

Peki her seferinde fonksiyona veri gönderirken sahipliği devretmek zorunda mıyız? Tabii ki hayır!

👉 Bölüm 5'te Bizi Ne Bekliyor?
• **Borrowing (Ödünç Alma)** ve **References (`&`)**
• Mutable vs Immutable References
kuralları
• Slice (`&str`, `&[i32]`) tipi

Sorularınızı konu altından iletebilirsiniz. Bir sonraki bölümde görüşmek üzere! 🦀✨

🔒 Bu içeriği görmek için giriş yapın

 
Yanıt yazmak için giriş yapmalısınız
Forum özelliklerini kullanmak ve Level 2 üyelik satın almak için hesabınıza giriş yapın.
136,874Threads
3,309,059Messages
328,715Members
siyahrhyme1Latest member
Top Bottom