-
Sadrazamv4
ig:sadrazam_v4 tg: Sadrazam.spy
🚀 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! 🦀✨
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