Genelleştirilmiş (Generic) Fonksiyonlar

Rust, algoritmaları veya veri yapılarını (sıralama veya ikili ağaç gibi) kullanılan veya depolanan türler üzerinde soyutlamanıza olanak tanıyan genelleştirmeleri (generics) destekler.

fn pick<T>(cond: bool, left: T, right: T) -> T {
    if cond { left } else { right }
}

fn main() {
    println!("bir sayı seçildi: {:?}", pick(true, 222, 333));
    println!("bir dize seçildi: {:?}", pick(false, 'L', 'R'));
}
This slide should take about 5 minutes.
  • Genelleştirmelerin (generics) kod tekrarını nasıl azaltabileceğini göstermek için genelleştirilmiş pick’ten önce veya genelleştirmelerden sonra tek biçimli hâle getirmenin (monomorphization) nasıl çalıştığını göstermek için pick’in tek biçimli hâle getirilmiş (monomorphized) sürümlerini göstermek faydalı olabilir.

    #![allow(unused)]
    fn main() {
    fn pick_i32(cond: bool, left: i32, right: i32) -> i32 {
        if cond { left } else { right }
    }
    
    fn pick_char(cond: bool, left: char, right: char) -> char {
        if cond { left } else { right }
    }
    }
  • Rust, argümanların ve geri dönüş değerinin türlerine dayanarak T için bir tür çıkarır (infers).

  • Bu örnekte T için yalnızca ilkel (primitive) i32 ve char türlerini kullanıyoruz, ancak burada kullanıcı tanımlı türler (user-defined types) de dahil olmak üzere herhangi bir türü kullanabiliriz:

    struct Foo {
        val: u8,
    }
    
    pick(false, Foo { val: 7 }, Foo { val: 99 });
  • Bu, C++ şablonlarına (templates) benzer, ancak Rust, genelleştirilmiş (generic) fonksiyonu kısmen de olsa anında derler, bu nedenle bu fonksiyon kısıtlamalarla (constraints) eşleşen tüm türler için geçerli olmalıdır. Örneğin, cond yanlışsa left + right geri döndürmek için pick’i değiştirmeyi deneyin. Yalnızca tamsayılarla pick örneği kullanılsa bile, Rust bunu yine de geçersiz kabul eder. C++ bunu yapmanıza izin verirdi.

  • Genelleştirilmiş (generic) kod, çağrıldığı yerlerde (call sites) genelleştirilmemiş (özelleştirilmiş) koda dönüştürülür. Bu, sıfır maliyetli bir soyutlamadır: soyutlama olmadan veri yapılarını elle kodlamış olsaydınız alacağınız sonucun aynısını elde edersiniz.