Ownership (Sahiplik) Sistemi: Rust’ın En Benzersiz Özelliği

  • Konbuyu başlatan Konbuyu başlatan irfo
  • Başlangıç tarihi Başlangıç tarihi

irfo

Moderatör
Top Poster Of Month
Katılım
7 Ocak 2026
Mesajlar
234
Tepkime puanı
2
Puanları
18
Rust dünyasına hoş geldiniz! Eğer daha önce C++ gibi dillerde manuel bellek yönetimiyle (malloc/free) saç baş yolduysanız ya da Java/Python gibi dillerde Garbage Collector (Çöp Toplayıcı) sisteminin arkada ne zaman çalışacağını merak ettiyseniz, Rust size bambaşka bir üçüncü yol sunuyor: Ownership (Sahiplik).

Bu sistem, Rust’ın "hızlı ama güvenli" olmasını sağlayan temel mekanizmadır. Gelin, bu kavramı bir yazılımcının gözünden, en basit haliyle inceleyelim.


1. Ownership (Sahiplik) Nedir?​

En temel tanımıyla Ownership, Rust derleyicisinin programın belleği nasıl yönettiğini kontrol eden bir kurallar dizisidir. Çoğu dil belleği iki şekilde yönetir: ya geliştirici her şeyi el ile temizler ya da bir "Garbage Collector" sistemi arka planda çalışarak kullanılmayan belleği tarar ve siler.

Rust'ta ise üçüncü bir yol vardır: Kurallara uymazsan kod derlenmez. Bu sayede çalışma zamanında (runtime) bellek hataları almazsınız, çünkü derleyici hataları daha kodu yazarken yakalar.

Ownership'in Üç Temel Kuralı​

Ownership sistemini anlamak için şu üç kuralı ezberlememiz gerekiyor:

  1. Rust’ta her değerin bir sahibi (owner) vardır.
  2. Bir değerin aynı anda yalnızca bir sahibi olabilir.
  3. Sahibi (owner) kapsam dışına (out of scope) çıktığında, değer otomatik olarak bellekten silinir.

2. Kapsam (Scope) Kavramı​

Bir değişkenin nerede doğup nerede öldüğünü bilmek çok önemlidir. Rust'ta değişkenler, tanımlandıkları süslü parantez { } içinde yaşarlar.

Kod:
{                      // s burada henüz tanımlı değillet s = "merhaba"; // s artık bu kapsamda geçerli// s ile işlemler yapılır...}                      // kapsam bitti, s artık geçerli değil ve bellek iade edildi

Bu basit bir yapı gibi görünse de, veriler yığın (stack) yerine öbek (heap) üzerinde depolandığında işler ilginçleşir.


3. Bellek Etkileşimi: Move (Taşıma)​

Rust'ta karmaşık veri tipleri (örneğin String) kopyalanmaz, taşınır. Diğer dillerde alışık olduğumuz "yüzeysel kopyalama" (shallow copy) burada farklı çalışır.

Kod:
let s1 = String::from("Selam");let s2 = s1; // s1'in verisi s2'ye TAŞINDI

// println!("{}", s1); // BU SATIR HATA VERİR!

Burada ne oldu? s1 değişkeni s2'ye atandığında, bellek adresi sahipliği el değiştirdi. Rust, s1'in artık geçersiz olduğunu kabul eder. Neden mi? Çünkü kapsam bittiğinde her iki değişken de aynı belleği silmeye çalışırsa (double free hatası), program çökerdi. Rust bunu derleme aşamasında engeller.


4. Borrowing (Ödünç Alma) ve Referanslar​

Her seferinde sahipliği devretmek zahmetli olabilir. Bir fonksiyona bir veriyi gönderip, işi bitince geri almak için sürekli sahiplik transferi yapmak yerine Referansları kullanırız. Buna "Ödünç Alma" denir.

Referans kullanmak için & sembolünü kullanırız:

Kod:
fn main() {let s1 = String::from("Rust");let uzunluk = uzunluk_hesapla(&s1); // s1'i sadece ödünç verdik

println!("'{}' kelimesinin uzunluğu: {}", s1, uzunluk); <br>// s1 hala burada kullanılabilir!<br>
}

fn uzunluk_hesapla(s: &String) -> usize { // s, bir String referansıdırs.len()}

Ödünç Alma Kuralları​

Rust, ödünç alma konusunda çok titizdir:

  • Aynı anda ya bir tane değiştirilebilir referans (&amp;mut T) alabilirsiniz.
  • Ya da istediğiniz kadar değiştirilemez referans (&amp;T) alabilirsiniz.
Aynı anda hem veriyi birine okuması için verip, hem de başka birine "bunu değiştirebilirsin" diyemezsiniz. Bu, veri yarışlarını (data races) tamamen ortadan kaldırır.


5. Değiştirilebilir Referanslar (Mutable Borrowing)​

Eğer ödünç verdiğiniz verinin değiştirilmesini istiyorsanız &amp;mut kullanmalısınız:

Kod:
fn main() {let mut s = String::from("Merhaba");metni_degistir(&mut s);println!("{}", s); // Çıktı: Merhaba Dünya}

fn metni_degistir(kelime: &mut String) {kelime.push_str(" Dünya");}


6. Slicing (Dilimleme): Verinin Bir Parçasına Sahip Olmak​

Slicing, bir koleksiyonun tamamına değil, sadece belirli bir kısmına referans vermenizi sağlar. Özellikle metin işlemlerinde hayat kurtarır.

Kod:
let s = String::from("Rust Programlama");

let rust = &s[0..4]; // 0. indisten 4. indise kadar (4 hariç)let programlama = &s[5..16];

println!("İlk kelime: {}", rust);

Dilimler (slices), sahipliği devralmazlar; sadece orijinal verinin belirli bir aralığını işaret eden özel referanslardır.


Özet: Neden Bu Kadar Karmaşık?​

İlk bakışta "Neden basitçe kopyalayıp geçmiyoruz?" diyebilirsiniz. Ancak Ownership sayesinde:

  1. Hız: Garbage Collector çalışmadığı için programınız duraksamaz.
  2. Güvenlik: Bellek sızıntıları (memory leaks) neredeyse imkansız hale gelir.
  3. Veri Yarışı Yok: Çoklu iş parçacığı (multithreading) kullanırken verilerin aynı anda bozulması engellenir.
Rust'ın bu katı kuralları, aslında sizin geceleri rahat uyumanızı sağlayan bir güvenlik ağıdır. Derleyici ile kavga etmeyi bıraktığınızda, onun aslında en iyi dostunuz olduğunu fark edeceksiniz.
 
Geri
Üst