Generic Metotlar
Coddy'nin Rust Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 25 / 61.
Generic bir struct herhangi bir türü tutabilir, ancak verileriyle etkileşime girecek metotlar olmadan pek kullanışlı değildir. Generic bir struct için metotlar tanımlamak için, impl bloğunda özel bir sözdizimine ihtiyacınız vardır.
Anahtar nokta, generic parametreyi impl bloğunun kendisinde tanımlamaktır:
struct Wrapper<T> {
value: T,
}
impl<T> Wrapper<T> {
fn get(&self) -> &T {
&self.value
}
}
Wrapper<T> öncesindeki impl<T> ifadesine dikkat edin. Bu, Rust'a T'nin tüm uygulama bloğu için genel bir tür parametresi olduğunu söyler. Bu bildirim olmadan Rust, T adında somut bir tür arayacak ve onu bulamayacaktır.
get metodu, sarmalayıcının (wrapper) tuttuğu tür ne olursa olsun ona bir referans olan &T değerini döndürür. Bu, T bir tam sayı, bir dize veya başka herhangi bir tür olsa da çalışır:
let num_wrapper = Wrapper { value: 100 };
let text_wrapper = Wrapper { value: "Rust" };
println!("{}", num_wrapper.get()); // 100
println!("{}", text_wrapper.get()); // Rust
Aynı metot tanımı her ikisi için de çalışır, çünkü genel (generic) T derleme zamanında her bir somut türe uyum sağlar.
Görev
KolayHadi genel kapsayıcınızı metotlarla genişletelim! Herhangi bir türü tutabilen ve içeriğiyle etkileşim kurmak için metotlar sağlayan bir Box struct'ı (Rust'ın standart Box yapısıyla karıştırılmamalıdır) oluşturacaksınız.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
mybox.rs:Ttüründe özel (private) bircontentsalanına sahip,MyBox<T>adında genel (generic) bir struct tanımlayın. Bu struct için şu metotları uygulayın:- Verilen değerle yeni bir
MyBoxoluşturan birnewilişkili fonksiyonu (associated function) - İçeriğe bir referans döndüren bir
peekmetodu (&selfkullanarak) - Yeni bir değer alan ve mevcut içeriği değiştiren bir
replacemetodu (&mut selfkullanarak)
- Verilen değerle yeni bir
main.rs: Modülünüzü dahil edin ve farklı türlerle çalışan genel metotları gösterin. Metotların işleyişini göstermek için kutular oluşturacak, içeriklerine göz atacak (peek) ve değerleri değiştireceksiniz.
Genel bir struct üzerinde metotları uygularken kullanılan anahtar söz dizimini unutmayın: Rust'a T'nin tüm uygulama bloğu için genel bir parametre olduğunu bildirmek için MyBox<T> ifadesinden önce impl<T> kullanmanız gerekir.
Ana dosyanızda, MyBox yapınızı şunları yaparak gösterin:
- Bir tam sayı ile bir kutu oluşturma (ilk girdi,
i32olarak ayrıştırılmış) - İçeriğine göz atma ve değeri yazdırma
- İçeriği yeni bir tam sayı ile değiştirme (ikinci girdi,
i32olarak ayrıştırılmış) - Güncellenmiş değeri göstermek için tekrar göz atma
- Bir dize (string) ile ikinci bir kutu oluşturma (üçüncü girdi)
- Dize kutusunun içeriğine göz atma
Çıktınız şu formatta olmalıdır:
Integer box contains: {value}
After replace: {value}
String box contains: {value}Örneğin, 10, 25 ve Rust girdileriyle:
Integer box contains: 10
After replace: 25
String box contains: RustÜç girdi alacaksınız: başlangıç tam sayısı, değiştirilecek tam sayı ve bir dize değeri.
Kopya kağıdı
Generic bir struct için metotlar tanımlamak için, generic parametreyi impl bloğunda bildirin:
struct Wrapper<T> {
value: T,
}
impl<T> Wrapper<T> {
fn get(&self) -> &T {
&self.value
}
}
impl<T> sözdizimi, Rust'a T'nin tüm uygulama bloğu için generic bir tür parametresi olduğunu bildirir. Bu olmadan Rust, T adında somut bir tür arayacaktır.
Metotlar, herhangi bir somut tür için çalışan generic türe (&T) referanslar döndürebilir:
let num_wrapper = Wrapper { value: 100 };
let text_wrapper = Wrapper { value: "Rust" };
println!("{}", num_wrapper.get()); // 100
println!("{}", text_wrapper.get()); // Rust
Kendin dene
mod mybox;
use mybox::MyBox;
fn main() {
// Girdileri oku
let mut input1 = String::new();
std::io::stdin().read_line(&mut input1).expect("Failed to read line");
let initial_int: i32 = input1.trim().parse().expect("Invalid integer");
let mut input2 = String::new();
std::io::stdin().read_line(&mut input2).expect("Failed to read line");
let replacement_int: i32 = input2.trim().parse().expect("Invalid integer");
let mut input3 = String::new();
std::io::stdin().read_line(&mut input3).expect("Failed to read line");
let string_value = input3.trim().to_string();
// TODO: Başlangıç tamsayısı ile bir MyBox oluşturun
// TODO: İçeriğine göz atın ve şunu yazdırın: "Integer box contains: {value}"
// TODO: İçeriği yedek tamsayı ile değiştirin
// TODO: Tekrar göz atın ve şunu yazdırın: "After replace: {value}"
// TODO: Dize değeri ile ikinci bir MyBox oluşturun
// TODO: Dize kutusuna göz atın ve şunu yazdırın: "String box contains: {value}"
}
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