Generic Fonksiyonlar
Coddy'nin Rust Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 27 / 61.
Generic'ler sadece struct'larla sınırlı değildir; herhangi bir tiple çalışan bağımsız fonksiyonlar da yazabilirsiniz. Bu, belirli bir struct'a ait olmayan ancak yine de esnek olması gereken bir yardımcı fonksiyona ihtiyaç duyduğunuzda kullanışlıdır.
Sözdizimi, struct'larda gördüklerinize benzer. Genel (generic) parametreyi fonksiyon adından sonra açılı ayraçlar içinde bildirin, ardından bunu parametrelerde ve dönüş türünde kullanın:
fn identity<T>(value: T) -> T {
value
}
Bu identity fonksiyonu, herhangi bir türden bir değer alır ve onu değiştirmeden döndürür. <T> jeneriği tanımlar, value: T bunu bir parametre olarak kabul eder ve -> T dönüş türünü belirtir. Fonksiyonu çağırdığınızda, Rust somut türü çıkarımlar:
let num = identity(42); // T, i32'dir
let text = identity("hello"); // T, &str'dir
Fonksiyonlarda da tıpkı struct'larda olduğu gibi birden fazla jenerik parametre kullanabilirsiniz:
fn make_pair<T, U>(first: T, second: U) -> (T, U) {
(first, second)
}
let pair = make_pair(10, "ten"); // (i32, &str) döndürür
Generic fonksiyonlar, tekrar kullanılabilir mantığı bir kez yazmanıza ve birçok türe uygulamanıza olanak tanıyarak, tip güvenliğini korurken kod tekrarını azaltır.
Görev
KolayHerhangi bir tiple çalışabilen genel (generic) fonksiyonlara sahip bir yardımcı modül oluşturalım! Belirli bir yapıya (struct) bağlı kalmadan, generic yapısının kodunuzu nasıl esnek ve yeniden kullanılabilir hale getirdiğini gösteren bağımsız fonksiyonlar oluşturacaksınız.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
utils.rs: Genel yardımcı fonksiyonlardan oluşan bir koleksiyon oluşturun:wrap_in_pair<T>— tek bir değer alır ve bu değeri iki kez içeren bir demet (tuple) döndürür:(value, value). Bu, tipinCloneolmasını gerektirir, bu nedenle<T: Clone>kullanın.swap<T, U>— potansiyel olarak farklı tiplerde iki değer alır ve bunları(U, T)şeklinde ters sırada bir demet olarak döndürür.
main.rs: Yardımcı modülünüzü içe aktarın ve bu generic fonksiyonların farklı tiplerle nasıl çalıştığını gösterin. Aynı fonksiyon tanımlarının tam sayıları, ondalıklı sayıları ve dizeleri (string) nasıl sorunsuz bir şekilde işlediğini gösterin.
Ana dosyanızda, yardımcı fonksiyonlarınızı şu şekilde gösterin:
- Bir tam sayı (ilk girdi,
i32olarak ayrıştırılmış) ilewrap_in_pairkullanın ve her iki öğeyi de yazdırın. - Bir dize (ikinci girdi) ile
wrap_in_pairkullanın ve her iki öğeyi de yazdırın. - Bir tam sayı (üçüncü girdi,
i32olarak ayrıştırılmış) ve bir dize (dördüncü girdi) ileswapkullanın, ardından yer değiştirmiş sonucu yazdırın.
Çıktınız şu formatta olmalıdır:
Pair of ints: ({value}, {value})
Pair of strings: ({value}, {value})
Swapped: ({string}, {int})Örneğin, 5, hello, 42 ve world girdileriyle:
Pair of ints: (5, 5)
Pair of strings: (hello, hello)
Swapped: (world, 42)wrap_in_pair fonksiyonunun hem tam sayılar hem de dizeler için nasıl aynı şekilde çalıştığına ve swap fonksiyonunun tamamen farklı iki tipi nasıl işlediğine dikkat edin; işte generic fonksiyonların esnekliği budur!
Dört girdi alacaksınız: bir tam sayı, bir dize, başka bir tam sayı ve başka bir dize.
Kopya kağıdı
Genel (generic) fonksiyonlar, herhangi bir tiple çalışan bağımsız yardımcı fonksiyonlar yazmanıza olanak tanır. Genel parametreyi fonksiyon adından sonra açılı ayraçlar içinde bildirin:
fn identity<T>(value: T) -> T {
value
}
<T>, fonksiyon parametrelerinde ve dönüş tiplerinde kullanılabilen genel tip parametresini bildirir. Rust, fonksiyonu çağırdığınızda somut tipi çıkarımlar:
let num = identity(42); // T, i32'dir
let text = identity("hello"); // T, &str'dir
Tek bir fonksiyonda birden fazla genel parametre kullanabilirsiniz:
fn make_pair<T, U>(first: T, second: U) -> (T, U) {
(first, second)
}
let pair = make_pair(10, "ten"); // (i32, &str) döndürür
Genel bir tipin belirli yeteneklere ihtiyacı olduğunda, trait sınırlarını (trait bounds) kullanın:
fn duplicate<T: Clone>(value: T) -> (T, T) {
(value.clone(), value)
}
Kendin dene
mod utils;
use std::io;
fn main() {
// Dört girişi oku
let mut input1 = String::new();
io::stdin().read_line(&mut input1).expect("Failed to read line");
let num1: i32 = input1.trim().parse().expect("Invalid integer");
let mut input2 = String::new();
io::stdin().read_line(&mut input2).expect("Failed to read line");
let str1 = input2.trim().to_string();
let mut input3 = String::new();
io::stdin().read_line(&mut input3).expect("Failed to read line");
let num2: i32 = input3.trim().parse().expect("Invalid integer");
let mut input4 = String::new();
io::stdin().read_line(&mut input4).expect("Failed to read line");
let str2 = input4.trim().to_string();
// TODO: num1 ile wrap_in_pair kullanın ve sonucu yazdırın
// Format: Pair of ints: ({value}, {value})
// TODO: str1 ile wrap_in_pair kullanın ve sonucu yazdırın
// Format: Pair of strings: ({value}, {value})
// TODO: num2 ve str2 ile swap kullanın, ardından yer değiştirilmiş sonucu yazdırın
// Format: Swapped: ({string}, {int})
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Object Oriented Programming bölümündeki tüm dersler
1Metotlar ve Davranış
Uygulama Bloklarına GirişSelf ParametresiDeğiştirilebilir Metotlarİlişkili FonksiyonlarBirden Fazla Uygulama BloğuMetot ZincirlemeÖzet - Dikdörtgen Eylemleri4Proje: Sanal Evcil Hayvan
Evcil Hayvanı TanımlamaEvcil Hayvanı Besleme2Kapsülleme ve Modüller
Modül TemelleriPublic Anahtar KelimesiPrivate AlanlarGetter'larSetter'larÖzet - Güvenli Kasa5Generic Yapılar
Generic Struct'larGeneric MetotlarÇoklu Generic TürlerGeneric FonksiyonlarÖzet - Koordinat Noktası8Sınırlandırıcı Olarak Trait'ler
Trait Sınırlandırıcı SözdizimiÇoklu SınırlandırıcılarWhere CümleciğiTrait'ler ile Tip DöndürmeÖzet - Generic Yazıcı11Rust'ta Tasarım Kalıpları
Newtype KalıbıKompozisyonDrop Trait'iFrom ve IntoÖzet - Smart Pointer Mock3İleri Seviye Enum'lar
Veri İçeren Enum'larEnum MetotlarıVeri Varyantlarını EşlemeOption Enum'ına Yeniden BakışÖzet - Shape Enum6Trait Tanımlama
Trait Nedir?Traitleri UygulamaVarsayılan UygulamalarVarsayılanları Geçersiz KılmaParametreli TraitlerÖzet - Media Player