🚀 BAŞTAN SONA RUST DİLİ BÖLÜM-6: Structs (Yapılar) ve Metotlar (`impl`) 🦀

Konu Özeti

Rust programlama dilinde struct (yapı) tanımlama, örnek oluşturma, alanlara erişim ve değiştirme işlemleri açıklanıyor. Field init shorthand ve struct update syntax gibi kısayollar ile tuple struct ve unit-like struct türleri gösteriliyor. impl bloklarıyla metot ve ilişkili fonksiyon tanımlama, self parametresinin kullanımı ve ownership kurallarına dikkat çekiliyor.

🚀 BAŞTAN SONA RUST DİLİ BÖLÜM-6: Structs (Yapılar) ve Metotlar (`impl`) 🦀

Selamlar! Serimizin 6. bölümüne hoş geldiniz.

Önceki bölümlerde Rust'ın temel veri tiplerini, Ownership (Sahiplik) ve Borrowing (Ödünç Alma) kurallarını öğrenmiştik. Bu bölümde ise kendi özel veri tiplerimizi oluşturmamızı sağlayan **Structs (Yapılar)** ve bu yapılara davranış ekleyen **`impl` (Metot) bloklarını** inceleyeceğiz.

---

📌 1. Struct (Yapı) Nedir? 🏗️

Struct, farklı veya aynı tipten birden fazla veriyi tek bir çatı altında toplamamızı sağlayan bileşik bir veri tipidir. Nesne Yönelimli Programlamadaki (OOP) class'ların "sadece veri tutan" haline benzetebilirsiniz.

Bir Struct tanımlamak için `struct` anahtar kelimesi kullanılır:

struct Kullanici {
kullanici_adi: String,
e_posta: String,
giris_sayisi: u64,
aktif_mi: bool,
}

---

✍️ 2. Struct Örneği (Instance) Oluşturmak 🛠️

Tanımladığımız Struct'tan bir değişken oluştururken tüm alanlara (field) değer atamamız gerekir.

fn main() {
let mut kullanici1 = Kullanici {
e_posta: String::from("[email protected]"),
kullanici_adi: String::from("ahmet123"),
aktif_mi: true,
giris_sayisi: 1,
};

// Alana erişmek ve değiştirmek (Değişken 'mut' olmalıdır!)
kullanici1.giris_sayisi += 1;
println!("Giriş Sayısı: {}", kullanici1.giris_sayisi);
}

> **Not:** Rust, bir Struct örneğinin sadece belirli alanlarını `mut` yapmanıza izin vermez. Örnek ya tamamen mutable'dır ya da değildir.

---

💡 3. Kısayollar ve Struct Update Syntax 🔄

### A. Field Init Shorthand
Eğer fonksiyon parametresi ile Struct alan adı aynıysa tekrar yazmanıza gerek yoktur:

fn kullanici_olustur(e_posta: String, kullanici_adi: String) -> Kullanici {
Kullanici {
e_posta, // e_posta: e_posta yerine
kullanici_adi, // kullanici_adi: kullanici_adi yerine
aktif_mi: true,
giris_sayisi: 1,
}
}

### B. Struct Update Syntax (`..`)
Mevcut bir Struct örneğindeki verileri kullanarak yeni bir örnek oluşturmak için `..` operatörünü kullanırız:

fn main() {
let kullanici1 = kullanici_olustur(
String::from("[email protected]"),
String::from("ahmet123")
);

let kullanici2 = Kullanici {
e_posta: String::from("[email protected]"),
..kullanici1 // Kalan tüm alanları kullanici1'den kopyala/taşı!
};
}

⚠️ **Ownership Uyarısı:** `kullanici1` içindeki `kullanici_adi` (String - Heap verisi) `kullanici2`'ye **Move** edildiği için `kullanici1` artık bütün olarak kullanılamaz!

---

🎯 4. Farklı Struct Tipleri 🎨

Rust'ta 3 farklı Struct türü vardır:

1. **Named-Field Struct:** Alan adı olan klasik struct (Yukarıdaki örnekler).
2. **Tuple Struct:** Alan adı olmayan, sadece veri tipleri belirtilen struct.
3. **Unit-Like Struct:** Hiçbir alan barındırmayan struct (İleride Trait'lerde kullanılacak).

// Tuple Struct Örneği
struct Renk(i32, i32, i32);
struct Nokta(i32, i32, i32);

// Unit-Like Struct Örneği
struct BosYapisi;

fn main() {
let siyah = Renk(0, 0, 0);
let orijin = Nokta(0, 0, 0);

println!("Kırmızı değeri: {}", siyah.0);
}

---

⚙️ 5. Metotlar ve `impl` Blokları 🛠️

Metotlar, fonksiyonlara benzer ancak bir Struct bağlamında (`impl` bloğu içinde) tanımlanırlar ve ilk parametreleri her zaman `self` olur.

struct Dikdortgen {
genislik: u32,
yukseklik: u32,
}

impl Dikdortgen {
// Alan Hesabı Yapan Metot
fn alan(&self) -> u32 {
self.genislik * self.yukseklik
}

// Başka bir dikdörtgeni kapsayıp kapsamadığını kontrol eden metot
fn kapsar_mi(&self, diger: &Dikdortgen) -> bool {
self.genislik > diger.genislik && self.yukseklik > diger.yukseklik
}
}

fn main() {
let dik1 = Dikdortgen { genislik: 30, yukseklik: 50 };
let dik2 = Dikdortgen { genislik: 10, yukseklik: 40 };

println!("Dikdörtgenin Alanı: {} px²", dik1.alan());
println!("dik1, dik2'yi kapsar mı? {}", dik1.kapsar_mi(&dik2));
}

#### `self` Parametresi Çeşitleri:
• `&self`: Veriyi sadece okumak için ödünç alır (En çok kullanılan).
• `&mut self`: Struct'ın alanlarını değiştirmek için ödünç alır.
• `self`: Struct'ın sahipliğini (ownership) tamamen alır ve tüketir (Nadir kullanılır).

---

🏭 6. Associated Functions (İlişkili Fonksiyonlar) 📌

`impl` bloğu içinde ilk parametresi `self` **OLMAYAN** fonksiyonlar tanımlayabiliriz. Bunlar metot değil, "İlişkili Fonksiyon"dur (OOP'deki static method gibi). Genellikle yapıcı (constructor) olarak kullanılırlar.

impl Dikdortgen {
// Kare oluşturan yapıcı fonksiyon
fn kare(boyut: u32) -> Self {
Self {
genislik: boyut,
yukseklik: boyut,
}
}
}

fn main() {
// Çağırırken '::' kullanılır
let kare1 = Dikdortgen::kare(20);
println!("Kare Alanı: {}", kare1.alan());
}

---

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

Bu bölümde Struct yapısını, veri gruplamayı, metot tanımlamayı ve `impl` bloklarının kullanımını öğrendik.

👉 **Bölüm 7'de Bizi Ne Bekliyor?**
• Rust'ın Süper Gücü: **Enums (Numaralandırmalar)**
• `Option<T>` Tipi (Rust'ta ne
den `null` yok?)
• **`match`** ve **`if let`** Deseni (Pattern Matching)

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,491Threads
3,305,933Messages
328,336Members
joker133Latest member
Top Bottom