Rust Ownership Kavramı: Başlangıç Rehberi (2025) | Memory Safety Nedir?

19.12.2025 11:05 Haber

Rust öğrenmeye başladınız ve "ownership" kavramını (ownership concept) duydunuz ama kafanız karıştı mı? Endişelenmeyin, yalnız değilsiniz! Alesta Web olarak Rust'ın en önemli ama en zorlu kavramı olan ownership'i (ownership is Rust's most important but most challenging concept) basit örneklerle açıklayacağız. Memory safety, borrowing ve lifetimes konularını (memory safety, borrowing and lifetimes topics) adım adım öğreneceksiniz. Bu rehber 2025'te Rust öğrenmek isteyenler için (for those who want to learn Rust in 2025) mükemmel bir başlangıç noktası!

Neden Ownership? Rust'ı Özel Yapan Nedir? (Why Ownership? What Makes Rust Special?)

Diğer programlama dillerinde (in other programming languages) memory yönetimi (memory management) iki şekilde yapılır:

Yaklaşım (Approach) Diller (Languages) Artıları (+) Eksileri (-)
Garbage Collection Java, Python, JavaScript, Go Kolay, güvenli (Easy, safe) Yavaş, öngörülemez pause'lar (Slow, unpredictable pauses)
Manuel Memory C, C++ Hızlı, kontrol (Fast, control) Memory leak, segfault, use-after-free
Ownership (Rust) Rust ✅ Hızlı + Güvenli (Fast + Safe) Öğrenme eğrisi (Learning curve)

Alesta Web ekibinin Rust deneyimine göre (according to Alesta Web team's Rust experience): Ownership başta zor görünse de (even though ownership seems difficult at first), bir kere anladığınızda C++'tan daha güvenli ve Python'dan daha hızlı kod yazabilirsiniz (you can write code safer than C++ and faster than Python)!

? Basit Açıklama:

Ownership, her değerin (every value) bir "sahibi" olduğu (has an "owner") ve bu sahibin değeri kullanma ve temizleme sorumluluğu taşıdığı (responsible for using and cleaning up the value) bir sistemdir. Garbage collector yok, manuel free() yok, ama memory güvenli (but memory safe)!

3 Temel Ownership Kuralı (3 Fundamental Ownership Rules)

Rust'ın ownership sistemi 3 basit kurala dayanır (Rust's ownership system is based on 3 simple rules):

Kural 1: Her Değerin Bir Sahibi Var (Each Value Has an Owner)

let s = String::from("hello");
// 's' değişkeni "hello" String'inin sahibidir
// 's' variable is the owner of the "hello" String

Kural 2: Aynı Anda Sadece Bir Sahip Olabilir (Only One Owner at a Time)

let s1 = String::from("hello");
let s2 = s1;  // Sahiplik s1'den s2'ye taşındı (ownership moved)

println!("{}", s1);  // ❌ HATA! s1 artık geçersiz (s1 no longer valid)

Kural 3: Sahip Scope'tan Çıktığında, Değer Drop Edilir (When Owner Goes Out of Scope, Value is Dropped)

{
    let s = String::from("hello");
    // s burada kullanılabilir (s is usable here)
} // s scope dışına çıktı, memory otomatik temizlendi!
  // (s went out of scope, memory automatically cleaned!)

// s artık kullanılamaz (s cannot be used anymore)

Alesta Web tavsiyesi: Bu 3 kuralı (these 3 rules) ezberleyin! Rust'ın %90'ı bu kurallar üzerine kurulu (90% of Rust is built on these rules).

Move Semantics: Sahiplik Taşınması (Move Semantics: Ownership Transfer)

Rust'ta bir değeri başka bir değişkene atadığınızda (when you assign a value to another variable), sahiplik "taşınır" (ownership is "moved"):

Örnek 1: String Move

fn main() {
    let s1 = String::from("Alesta Web");
    let s2 = s1;  // s1'den s2'ye MOVE (MOVE from s1 to s2)

    println!("{}", s2);  // ✅ Çalışır: "Alesta Web"
    println!("{}", s1);  // ❌ COMPILE ERROR!
}

// Hata mesajı (Error message):
// error[E0382]: borrow of moved value: `s1`

Neden? Çünkü String heap'te (on the heap) tutulur ve iki pointer'ın aynı memory'yi göstermesi (two pointers pointing to same memory) double-free bug'ına yol açar. Rust bunu engellemek için (to prevent this) ownership'i taşır!

Örnek 2: Copy vs Move

fn main() {
    // Integer'lar Copy trait'ine sahip (have Copy trait)
    let x = 5;
    let y = x;

    println!("x: {}, y: {}", x, y);  // ✅ İkisi de çalışır! (Both work!)

    // String'ler Copy trait'ine sahip DEĞİL (DON'T have Copy trait)
    let s1 = String::from("hello");
    let s2 = s1;

    println!("{}", s1);  // ❌ HATA!
}

Basit tipler (simple types) stack'te tutulur ve kopyalanması ucuzdur (copying is cheap), o yüzden Copy yapılır. Karmaşık tipler (complex types) heap'te tutulur, Move yapılır.

✅ Copy Trait'ine Sahip Tipler:
  • Integer'lar: i32, u64, vb. (Integers)
  • Float'lar: f32, f64
  • Boolean: bool
  • Char: char
  • Tuple'lar (sadece Copy elemanlarsa / only if elements are Copy)

alestaweb.com üzerindeki Rust type system rehberimizde daha fazla detay bulabilirsiniz (you can find more details in our Rust type system guide).

Borrowing: Sahipliği Taşımadan Kullanma (Borrowing: Using Without Taking Ownership)

Peki sahipliği taşımadan (without transferring ownership) bir değeri kullanmak istersek? İşte burada borrowing (ödünç alma) devreye giriyor!

Immutable Reference (&T)

fn main() {
    let s1 = String::from("Alesta Web");

    // s1'i ödünç al (borrow s1) ama sahipliği taşıma (but don't take ownership)
    let len = calculate_length(&s1);

    println!("'{}' uzunluğu: {}", s1, len);  // ✅ s1 hala kullanılabilir!
}

fn calculate_length(s: &String) -> usize {
    s.len()  // Sadece okuma yapıyoruz (just reading)
}  // s scope dışı, ama String drop edilmez (s goes out of scope, but String is NOT dropped)
   // çünkü sahip değiliz! (because we don't own it!)

&s1 syntax'ı bir "reference" (referans) oluşturur. Reference sahiplik almaz (reference doesn't take ownership), sadece değere erişim sağlar (just provides access to the value).

Borrowing Kuralları (Borrowing Rules)

fn main() {
    let s = String::from("hello");

    // Aynı anda birden fazla immutable reference OK! ✅
    let r1 = &s;
    let r2 = &s;
    let r3 = &s;

    println!("{}, {}, {}", r1, r2, r3);  // ✅ Hepsi çalışır!
}

İstediğiniz kadar immutable reference oluşturabilirsiniz (you can create as many immutable references as you want). Sadece okuma yaptıkları için (since they only read) sorun yok!

? Alesta Web Analojisi:

Kitap ödünç vermek gibi düşünün (think of it like lending a book): Kitabınızı arkadaşınıza verdiniz (&referans), o okuyor ama kitap hala sizin (it's still yours). Arkadaşınız bitirince (reference scope ends) kitap size geri geliyor. Birden fazla kişi aynı kitabı okuyabilir ama hiç kimse sayfaları yırtamaz (no one can tear pages) çünkü immutable!

Mutable Borrowing: Değiştirilebilir Referanslar (Mutable Borrowing: Mutable References)

Eğer ödünç aldığımız değeri değiştirmek istiyorsak (if we want to modify the borrowed value), mutable reference kullanırız:

Mutable Reference (&mut T)

fn main() {
    let mut s = String::from("hello");

    change(&mut s);  // Mutable reference geçiyoruz (passing mutable reference)

    println!("{}", s);  // "hello, world!"
}

fn change(s: &mut String) {
    s.push_str(", world!");  // String'i değiştiriyoruz! (modifying String!)
}

Dikkat edin: s değişkeni mut olmalı (must be mut) ve &mut s ile mutable reference oluşturuyoruz.

⚠️ ÖNEMLİ KURAL: Tek Mutable Reference! (IMPORTANT RULE: Only One Mutable Reference!)
fn main() {
    let mut s = String::from("hello");

    let r1 = &mut s;
    let r2 = &mut s;  // ❌ COMPILE ERROR!

    println!("{}, {}", r1, r2);
}

// error[E0499]: cannot borrow `s` as mutable more than once at a time

Aynı anda sadece BİR tane mutable reference olabilir (only ONE mutable reference at a time)! Bu data race'i (data race) compile-time'da önler (prevents at compile-time).

Immutable ve Mutable Karıştırılamaz! (Cannot Mix Immutable and Mutable!)

fn main() {
    let mut s = String::from("hello");

    let r1 = &s;      // ✅ immutable borrow
    let r2 = &s;      // ✅ immutable borrow
    let r3 = &mut s;  // ❌ HATA! Immutable reference varken mutable olamaz
                       // (Cannot have mutable while immutable exists)

    println!("{}, {}, {}", r1, r2, r3);
}
✅ Çözüm: Scope Yönetimi (Solution: Scope Management)
fn main() {
    let mut s = String::from("hello");

    let r1 = &s;
    let r2 = &s;
    println!("{} and {}", r1, r2);
    // r1 ve r2 artık kullanılmıyor (r1 and r2 no longer used)

    let r3 = &mut s;  // ✅ ARTIK OK! (NOW OK!)
    println!("{}", r3);
}

Alesta Web notu: Rust 2018 edition'dan beri (since Rust 2018 edition), reference'ların son kullanımından sonra (after last use of references) yeni borrow yapabilirsiniz. Bu "Non-Lexical Lifetimes" (NLL) özelliği.

Lifetimes: Reference'lar Ne Kadar Yaşar? (Lifetimes: How Long Do References Live?)

Lifetime, bir reference'ın ne kadar süre geçerli olduğunu (how long a reference is valid) belirtir. Çoğu zaman Rust bunu otomatik çıkarır (Rust infers this automatically most of the time) ama bazen açıkça belirtmeniz gerekir (sometimes you need to specify explicitly).

Dangling Reference Sorunu (Dangling Reference Problem)

fn main() {
    let r;

    {
        let x = 5;
        r = &x;  // ❌ HATA! x scope dışına çıkacak
                 // (ERROR! x will go out of scope)
    }

    println!("{}", r);  // r artık geçersiz memory'yi gösterir!
                         // (r would point to invalid memory!)
}

// error[E0597]: `x` does not live long enough

Rust compile-time'da bunu engelliyor (prevents this at compile-time)! C++'ta bu segmentation fault olurdu (this would be a segfault in C++).

Lifetime Annotation Örneği (Lifetime Annotation Example)

// Hangi reference daha uzun yaşıyor? (Which reference lives longer?)
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

fn main() {
    let s1 = String::from("Alesta");
    let s2 = String::from("Web");

    let result = longest(&s1, &s2);
    println!("En uzun: {}", result);  // "Alesta"
}

'a lifetime parametresi (lifetime parameter), return edilen reference'ın x ve y'den en az biri kadar yaşayacağını (will live at least as long as one of x or y) garanti eder.

? Başlangıç İpucu:

Lifetime'lar başlangıçta kafa karıştırıcıdır (lifetimes are confusing at first). Alesta Web tavsiyesi: İlk başta lifetime yazmadan kod yazın (write code without lifetimes at first), compiler hata verirse (if compiler gives error) o zaman lifetime ekleyin. Compiler size tam olarak ne yapmanız gerektiğini söyleyecektir (will tell you exactly what to do)!

Gerçek Dünya Örnekleri (Real World Examples)

Örnek 1: Vector'de Değişiklik (Modifying a Vector)

fn main() {
    let mut numbers = vec![1, 2, 3, 4, 5];

    // Immutable borrow - sadece okuma (just reading)
    for num in &numbers {
        println!("{}", num);
    }

    // Mutable borrow - değiştirme (modifying)
    for num in &mut numbers {
        *num *= 2;  // Her elemanı 2 ile çarp (multiply each element by 2)
    }

    println!("{:?}", numbers);  // [2, 4, 6, 8, 10]
}

Örnek 2: Struct ile Ownership

struct User {
    name: String,
    email: String,
}

fn main() {
    let user1 = User {
        name: String::from("alestaweb"),
        email: String::from("info@alestaweb.com"),
    };

    // user1'i ödünç al (borrow user1)
    print_user(&user1);

    // user1 hala kullanılabilir! (user1 still usable!)
    println!("User: {}", user1.name);
}

fn print_user(user: &User) {
    println!("Name: {}, Email: {}", user.name, user.email);
}

Örnek 3: String Manipulation

fn main() {
    let mut text = String::from("Alesta");

    append_web(&mut text);

    println!("{}", text);  // "Alesta Web"
}

fn append_web(s: &mut String) {
    s.push_str(" Web");  // String'e ekleme (appending to String)
}

Alesta Web ekibinin Rust projelerinde (in Rust projects) en çok kullandığı pattern'ler bunlar (these are the most used patterns). alestaweb.com üzerinde daha fazla Rust örneği bulabilirsiniz.

Sık Yapılan Hatalar ve Çözümleri (Common Mistakes and Solutions)

❌ Hata 1: Move Edilen Değeri Kullanma (Using Moved Value)

// YANLIŞ (WRONG):
let s1 = String::from("hello");
let s2 = s1;
println!("{}", s1);  // HATA!

// DOĞRU (CORRECT):
let s1 = String::from("hello");
let s2 = s1.clone();  // Explicit clone
println!("{}, {}", s1, s2);  // ✅ İkisi de çalışır

clone() pahalı bir işlemdir (expensive operation). Mümkünse borrowing kullanın (use borrowing if possible)!

❌ Hata 2: Birden Fazla Mutable Reference (Multiple Mutable References)

// YANLIŞ (WRONG):
let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s;  // HATA!

// DOĞRU (CORRECT):
let mut s = String::from("hello");
{
    let r1 = &mut s;
    r1.push_str(" world");
}  // r1 scope dışı (r1 goes out of scope)
let r2 = &mut s;  // ✅ Artık OK!

❌ Hata 3: Return Dangling Reference

// YANLIŞ (WRONG):
fn dangle() -> &String {
    let s = String::from("hello");
    &s  // HATA! s drop edilecek (s will be dropped)
}

// DOĞRU (CORRECT):
fn no_dangle() -> String {
    let s = String::from("hello");
    s  // Sahipliği taşı (move ownership)
}

Alesta Web deneyimi: Bu hatalar başlangıçta sıkça yapılır (these errors are frequently made at first) ama Rust compiler çok yardımcıdır (Rust compiler is very helpful). Hata mesajlarını okuyun (read error messages), genelde çözümü gösterir (usually shows the solution)!

? Kaynaklar ve Referanslar / Sources and References

Bu makalede kullanılan bilgiler aşağıdaki güvenilir kaynaklardan alınmıştır (information used in this article is from the following reliable sources):

Alesta Web olarak tüm kavramları gerçek Rust projelerinde test ettik ve doğruladık (we tested and verified all concepts in real Rust projects).

✅ Ownership'i Anladınız! Şimdi Ne Yapmalı? (You Understood Ownership! What's Next?)

Alesta Web olarak size ownership kavramını (ownership concept) basit örneklerle anlattık. Bu Rust'ın temeli (this is the foundation of Rust) ve bir kere anladığınızda her şey çok daha kolay olacak (everything will be much easier once you understand)!

Hızlı Hatırlatıcı / Quick Reminder:

  • ✅ Her değerin bir sahibi var (Every value has one owner)
  • ✅ Aynı anda tek sahip (Only one owner at a time)
  • ✅ Sahip scope dışı çıkınca drop (When owner goes out of scope, drop)
  • ✅ Borrowing ile sahiplik almadan kullan (Use without taking ownership with borrowing)
  • ✅ İstediğin kadar &T, ama tek &mut T (As many &T as you want, but only one &mut T)
  • ✅ Compiler senin dostun! (Compiler is your friend!)

Sonraki Adımlar / Next Steps:

  1. Pratik Yapın! Küçük Rust programları yazın (write small Rust programs). alestaweb.com üzerindeki Rust egzersizlerimizi deneyin.
  2. Error Messages Okuyun: Rust compiler en iyi öğretmeniniz (best teacher). Her hata mesajını dikkatlice okuyun (read each error message carefully).
  3. Trait'leri Öğrenin: Copy, Clone, Drop trait'lerini anlayın (understand Copy, Clone, Drop traits).
  4. Gerçek Proje Yapın: CLI tool, web server veya küçük bir oyun (CLI tool, web server or small game).

Faydalı Linkler / Useful Links:

  • Alesta Web Ana Sayfa: alestaweb.com - Daha fazla Rust ve programlama rehberi (More Rust and programming guides)
  • Rust İleri Seviye Konular: alestaweb.com - Trait, Lifetime, Smart Pointer rehberleri
  • Rust Proje Örnekleri: alestaweb.com - Gerçek dünya Rust uygulamaları (Real world Rust applications)
? Rust Yolculuğunuzda Başarılar!

Ownership kavramını anlamak Rust öğrenmenin en zor kısmı (understanding ownership is the hardest part of learning Rust). Bunu geçtiniz, artık yolun yarısındasınız! Sorularınız için alestaweb.com üzerinden Alesta Web ekibine ulaşabilirsiniz.

© 2025 AlestaWeb - Tüm hakları saklıdır. Bu rehber Alesta Web tarafından hazırlanmıştır.

WM Tools
💫

WebMaster Tools

15 Profesyonel Araç