irfo
Moderatör
- Katılım
- 7 Ocak 2026
- Mesajlar
- 290
- Tepkime puanı
- 2
- Puanları
- 18
Rust'ta Genericler (Genel Tipler), kod tekrarını önlemenin ve farklı veri tipleriyle çalışabilen esnek yapılar kurmanın anahtarıdır. Genericler sayesinde bir fonksiyonu veya veri yapısını belirli bir tip (i32, f64, String) yerine, "herhangi bir tip" (T) için bir kez yazarsınız.
Rust'ın en büyük gücü, bu esnekliği sağlarken performanstan ödün vermemesidir.
Rust'ın en büyük gücü, bu esnekliği sağlarken performanstan ödün vermemesidir.
1. Generic Fonksiyon Tanımlama
Bir fonksiyonu generic yapmak için, fonksiyon adından sonra küçüktür/büyüktür işaretleri <T> içinde bir tip parametresi eklenir. T harfi gelenekseldir ("Type" kelimesini temsil eder), ancak istediğiniz ismi verebilirsiniz.
Kod:
// Herhangi bir tipteki iki öğeyi bir slice (dilim) içinde bulan fonksiyonfn listeyi_yazdir<T: std::fmt::Display>(liste: &[T]) {for oge in liste {println!("Öğe: {}", oge);}}
fn main() {let sayilar = vec![10, 20, 30];let kelimeler = vec!["Rust", "Esnektir"];
listeyi_yazdir(&sayilar); // T burada i32 olur<br>listeyi_yazdir(&kelimeler); // T burada &str olur<br>
}
2. Generic Veri Yapıları (Struct & Enum)
Sadece fonksiyonlar değil, struct ve enum yapıları da generic olabilir. Rust'ın en meşhur tipleri olan Option<T> ve Result<T, E> aslında birer generic enum'dır.
Kod:
struct Nokta<T> {x: T,y: T,}
fn main() {let tam_sayi = Nokta { x: 5, y: 10 }; // Nokta<i32>let ondalikli = Nokta { x: 1.0, y: 4.5 }; // Nokta<f64>}
Dikkat: Yukarıdaki örnekte x ve y aynı T tipine bağlıdır. Eğer x'in i32, y'nin f64 olmasını istiyorsanız, iki farklı generic parametre kullanmalısınız: struct Nokta<T, U>.
3. Trait Bounds (Trait Sınırları)
Generic bir tip (T) varsayılan olarak "her şey" olabilir. Ancak bazen T tipinin belirli özelliklere sahip olmasını istersiniz (örneğin; "T tipi ekrana yazdırılabilir olmalı" veya "T tipi toplanabilir olmalı"). Buna Trait Bounds denir.
Kod:
// Sadece karşılaştırılabilir (PartialOrd) tiplerle çalışan fonksiyonfn en_buyugu_bul<T: PartialOrd>(liste: &[T]) -> &T {let mut en_buyuk = &liste[0];for oge in liste {if oge > en_buyuk {en_buyuk = oge;}}en_buyuk}[CODE]
[HR][/HR]
[HEADING=1]4. Performans: Monomorphization[/HEADING]
Pek çok dilde generic yapılar çalışma zamanında (runtime) yavaşlamaya neden olur. Rust'ta ise durum farklıdır. Rust derleyicisi, generic kodu kullandığınız her somut tip için ayrı bir kopya oluşturur. Buna Monomorphization denir.
Örneğin, Nokta<i32> ve Nokta<f64> kullandığınızda, derleyici arka planda iki özel struct oluşturur. Bu sayede çalışma zamanında hiçbir "tip kontrolü" yapılmaz ve kod, sanki her tip için ayrı yazılmış gibi en yüksek hızda çalışır.
[HR][/HR]
[HEADING=1]5. Where İfadeleri ile Temiz Kod[/HEADING]
Çok fazla generic parametre ve sınır olduğunda fonksiyon imzası okunmaz hale gelebilir. where bloğu, bu sınırları düzenli bir şekilde alta yazmanızı sağlar.
[CODE=rust]fn karmasik_fonksiyon<T, U>(t: T, u: U) -> i32whereT: Display + Clone,U: Clone + Debug,{// Fonksiyon gövdesi0}
Özet
- Genericler, kodunuzu farklı tipler için tekrar kullanılabilir hale getirir.
- Trait Bounds, generic tiplerin yeteneklerini kısıtlayarak güvenli işlem yapmanızı sağlar.
- Monomorphization sayesinde generic kodlar "sıfır maliyetli"dir (performans kaybı yaşatmaz).