Rust Ownership ve Borrowing: Her Seyi Aciklayan Kapsamli Rehber
Rust ownership ve borrowing kavramlarini pratik orneklerle ogrenin. Move semantikleri, referanslar, lifetime'lar ve borrow checker ile guvenli, performansli Rust kodu yazmayi kesfedin.

Rust'ta ownership ve borrowing, dilin bellek guvenligini saglayan temel mekanizmalari olusturur. Garbage collector kullanan dillerden farkli olarak Rust, derleme zamaninda borrow checker araciligiyla kati kurallar uygulayarak null pointer hatalari, veri yarislari ve use-after-free gibi hata siniflarini calisma zamani maliyeti olmadan tamamen ortadan kaldirir.
Rust'ta her degerin tam olarak bir sahibi (owner) vardir. Sahip kapsam disindan ciktiginda deger bellekten silinir (drop). Sahiplik aktarilabilir (move) veya gecici olarak odunc verilebilir (borrow). Bu uc kural, garbage collection mekanizmasinin yerini tamamen alir.
Move Semantikleri Garbage Collection'in Yerini Nasil Alir
Cogu programlama dili, birden fazla degiskenin heap'te ayrilmis ayni veriye isaret etmesine izin verir. Rust farkli bir yaklasim benimser: heap uzerindeki bir degeri baska bir degiskene atamak, degeri tasir (move) ve orijinal baglamayi gecersiz kilar. Derleyici bunu sifir maliyetle zorunlu kilar.
fn main() {
let original = String::from("interview prep");
let moved = original; // ownership transfers here
// println!("{}", original); // compile error: value moved
println!("{}", moved); // works fine
}Bu yaklasim double-free hatalarini onler. String tipi heap uzerinde bellek ayirimi yapar, bu nedenle Rust herhangi bir anda yalnizca bir degiskenin bu ayirima sahip olmasini garanti eder. i32 veya bool gibi yalnizca stack uzerinde yasayan tipler Copy trait'ini implemente eder ve tasima yerine kopyalanir.
fn main() {
let x: i32 = 42;
let y = x; // copy, not move -- i32 is Copy
println!("x = {}, y = {}", x, y); // both valid
let s1 = String::from("hello");
let s2 = s1.clone(); // explicit deep copy
println!("s1 = {}, s2 = {}", s1, s2); // both valid after clone
}Copy ve Clone arasindaki fark mulakatlarda onemli bir konudur: Copy ortuk ve ucuzdur (bit duzeyi kopyalama), Clone ise acik ve maliyetli olabilir (heap ayirimi gerektirebilir).
Degismez Referanslarla Borrowing
Sahipligi her yere aktarmak kodu kullanilamaz hale getirir. Rust borrowing mekanizmasi, sahipligi aktarmadan bir degere erisim odunc vererek bu sorunu cozer. Degismez bir referans (&T) yalnizca okuma erisimi saglar ve birden fazla degismez referans ayni anda bir arada var olabilir.
fn calculate_length(s: &String) -> usize {
s.len() // read access through the reference
} // s goes out of scope, but doesn't drop the String (not the owner)
fn main() {
let greeting = String::from("hello, Rust");
let len = calculate_length(&greeting); // borrow, don't move
println!("'{}' has {} characters", greeting, len); // greeting still valid
}& sembol bir referans olusturarak degeri odunc alir. Fonksiyon imzasindaki &String, calculate_length fonksiyonunun sahiplik almadan odunc aldigini bildirir. Fonksiyon donduktaen sonra cagrici tam sahipligini korur.
Herhangi bir anda, bir deger ya birden fazla degismez referansa (&T) ya da tam olarak bir degistirilebilir referansa (&mut T) sahip olabilir. Asla her ikisi ayni anda olamaz. Bu kural, derleme zamaninda veri yarislarini onler.
Degistirilebilir Referanslar ve Mustakillik Kurali
Degistirilebilir referanslar (&mut T) yazma erisimi saglar ancak mustakillik zorunlulugu getirir: belirli bir kapsamda bir degere yalnizca bir degistirilebilir referans bulunabilir. Bu, iki farkli kod parcasinin ayni veriyi esanli olarak degistirmesini engeller.
fn append_greeting(s: &mut String) {
s.push_str(", welcome to Rust!"); // modify through mutable ref
}
fn main() {
let mut message = String::from("Hello");
append_greeting(&mut message);
println!("{}", message); // "Hello, welcome to Rust!"
}mut anahtar sozcugu uc yerde gorulur: degisken baglamada (let mut), referans tipinde (&mut) ve fonksiyon parametresinde. Her ucu de zorunludur. Ayni kapsamda ikinci bir degistirilebilir referans olusturmaya calismak derleme hatasina neden olur.
fn main() {
let mut data = String::from("shared state");
let r1 = &mut data;
// let r2 = &mut data; // compile error: second mutable borrow
println!("{}", r1);
// After r1's last usage, a new mutable borrow is allowed
let r3 = &mut data; // this works -- non-lexical lifetimes
r3.push_str(" updated");
println!("{}", r3);
}Rust 2021 surumu leksik olmayan yasamsureleri (NLL - Non-Lexical Lifetimes) kullanir: bir odunc alma, kapsam blogunun sonunda degil, son kullanim noktasinda sona erer. Bu, guvenligi feda etmeden mustakillik kuralini daha ergonomik hale getirir.
Rust mülakatlarında başarılı olmaya hazır mısın?
İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.
Lifetime'lar: Derleyiciye Referanslarin Ne Kadar Yasadigini Soyleme
Lifetime'lar, Rust'in referanslarin isaret ettigi veriden daha uzun yasamasini engellemesinin yoludur. Cogu durumda derleyici, lifetime elision kurallari araciligiyla lifetime'lari otomatik olarak cikarir. Birden fazla referansin etkilesime girdigi durumlarda acik annotasyonlar gerekli hale gelir.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
fn main() {
let result;
let string1 = String::from("Rust ownership");
{
let string2 = String::from("borrowing");
result = longest(string1.as_str(), string2.as_str());
println!("Longest: {}", result);
}
}'a sozdizimi bir lifetime parametresidir -- yeni bir kavram degil, halihazirda var olan iliskileri isaretler. Fonksiyon imzasi su anlama gelir: "cikis referansi, herhangi bir giris referansindan daha uzun yasamaz." Derleyici bunu sarkan referanslari (dangling references) onlemek icin kullanir.
Struct'larda Borrowing ve Lifetime Sinirlari
Referans tutan struct'lar lifetime parametreleri bildirmek zorundadir. Bu, struct'in referans verdigi veriden daha uzun yasamasini engeller -- C/C++'da sarkan isaretcilerin (dangling pointer) yaygin bir kaynagi olan bu sorun Rust'ta tamamen ortadan kaldirilir.
struct Excerpt<'a> {
text: &'a str,
}
impl<'a> Excerpt<'a> {
fn summary(&self) -> &str {
let end = self.text.len().min(20);
&self.text[..end]
}
}
fn main() {
let article = String::from("Rust ownership model eliminates memory bugs");
let excerpt = Excerpt {
text: article.as_str(),
};
println!("Summary: {}", excerpt.summary());
}Excerpt<'a> icindeki 'a lifetime'i, struct'in gecerliligini temel alindigi string'e baglar. article degiskenini excerpt'tan once bellekten silmek derleme hatasina yol acar.
Sarkan referans (dangling reference) sorulari Rust mulakatlarinda sikca karsimiza cikar. Cevap her zaman aynidir: Rust, derleme zamaninda lifetime analizi ile bunlari onler. Calisma zamani kontrolu yoktur, null isaretci yoktur.
Gercek Dunyada Ownership Kaliplari
Uretim ortamindaki Rust kodu birkaç tekrarlanan ownership kalibina dayanir. Bu kaliplari tanimak hem gelistirme hizini hem de mulakat performansini arttirir.
// Pattern 1: Take ownership, return a new value
fn process_and_return(mut input: String) -> String {
input.push_str(" -- processed");
input
}
// Pattern 2: Borrow for read-only inspection
fn contains_keyword(text: &str, keyword: &str) -> bool {
text.to_lowercase().contains(&keyword.to_lowercase())
}
// Pattern 3: Borrow mutably for in-place modification
fn sanitize(input: &mut String) {
*input = input.trim().to_string();
}
fn main() {
let raw = String::from("user input");
let processed = process_and_return(raw);
let found = contains_keyword(&processed, "input");
println!("Contains 'input': {}", found);
let mut padded = String::from(" spaces everywhere ");
sanitize(&mut padded);
println!("Sanitized: '{}'", padded);
}Bu kalipler arasinda secim yapmak basit bir sezgisel kurala dayanir: varsayilan olarak degismez odunc alma tercih edilir, degisiklik gerektiginde degistirilebilir odunc alma kullanilir ve yalnizca cagricinin degere artik ihtiyaci kalmadiginda sahiplik aktarilir. Bu yaklasim Rust temelleri rehberinde ayrintili olarak ele alinmaktadir.
Borrow Checker Hatalari ve Cozum Yollari
Borrow checker belirli hata kodlari uretir. En yaygin olanlari anlamak, sinir bozucu derleme hatalarini basit duzelmelere donusturur.
fn main() {
let mut scores = vec![90, 85, 78];
let first = scores[0];
scores.push(95);
println!("First: {}, All: {:?}", first, scores);
let name = String::from("Alice");
let greeting = format!("Hello, {}", name);
println!("{} says {}", name, greeting);
let outer;
{
let inner = String::from("temporary");
outer = inner;
}
println!("{}", outer);
}Her duzeltme ayni ilkeye dayanir: kodu, odunc alma ve sahiplik yapisinin Rust kurallariyla uyumlu olacagi sekilde yeniden yapilandirmak. Borrow checker ile mucadele etmek genellikle diger dillerde hatalara yol acacak bir tasarim sorununa isaret eder. Esanlilik ve borrowing iceren daha ileri duzey kalipler icin Arc ve Mutex gibi paylasimli sahiplik tipleri vazgecilmez hale gelir.
Pratik yapmaya başla!
Mülakat simülatörleri ve teknik testlerle bilgini test et.
Sonuc
- Her Rust degerinin bir sahibi vardir; tip
Copyimplemente etmedikce atamada sahiplik aktarilir (move semantikleri) - Degismez referanslar (
&T) paylasimli okuma erisimi saglar; degistirilebilir referanslar (&mut T) ozel yazma erisimini zorunlu kilar - Borrow checker, derleme zamaninda veri yarislarini ve sarkan referanslari sifir calisma zamani maliyetiyle onler
- Lifetime'lar referans iliskilerini isaretler -- yeni kisitlamalar degil, var olan kisitlamalari tanimlar
- Borrow checker kodu reddettikinde,
unsafe'e basvurmak yerine sahiplik akisini yeniden yapilandirmak gerekir - Teknik mulakatlara hazirlik icin bu kaliplari Rust mulakat sorulari ile pratik yapmak akiciligi arttirir
Etiketler
Paylaş
İlgili makaleler

Rust'ta Ownership ve Borrowing: Eksiksiz Kılavuz
Rust'ın ownership ve borrowing sistemini ustalaşın. Sahiplik kuralları, referanslar, lifetime'lar ve gelişmiş bellek yönetimi desenleri.

Rust Mulakat Sorulari: 2026 Kapsamli Rehber
En sik sorulan 25 Rust mulakat sorusu. Ownership, borrowing, lifetime, trait, async/await, es zamanlilik konulari detayli cevaplar ve kod ornekleriyle.

Rust: 2026'da Deneyimli Geliştiriciler İçin Temel Kavramlar
Mevcut programlama bilgisiyle Rust'ı hızlıca öğrenmek mümkün. Sahiplik, ödünç alma, yaşam süreleri ve temel kalıplar; C++, Java veya Python'dan gelen geliştiriciler için açıklandı.