Dinamik Gönderim
Coddy'nin Rust Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 45 / 61.
<T: Summary> gibi özellik sınırlarıyla generic'leri kullandığınızda Rust, tam türü derleme zamanında belirler. Buna statik gönderim denir: derleyici, kullandığınız her somut tür için özelleştirilmiş kod oluşturur. Bu hızlıdır, ancak bir sınırlaması vardır: bir değişken yalnızca tek bir belirli türü tutabilir.
Çalışma zamanında farklı türleri tutabilecek tek bir değişkene ihtiyacın olursa ne olur? İşte burada özellik nesneleri devreye girer. Box<dyn Trait> kullanarak, özelliği uygulayan herhangi bir türü depolayabilirsin:
trait Speak {
fn speak(&self) -> String;
}
struct Dog;
struct Cat;
impl Speak for Dog {
fn speak(&self) -> String { String::from("Woof!") }
}
impl Speak for Cat {
fn speak(&self) -> String { String::from("Meow!") }
}
fn main() {
let animal: Box<dyn Speak> = Box::new(Dog);
println!("{}", animal.speak()); // "Woof!"
let animal: Box<dyn Speak> = Box::new(Cat);
println!("{}", animal.speak()); // "Meow!"
}
dyn anahtar sözcüğü dinamik dağıtımı belirtir: Rust, hangi yöntemin çağrılacağını derleme zamanında değil, çalışma zamanında arar. Trait nesnelerinin bilinen bir boyutu olmadığı için Box gereklidir; Box sabit boyutlu bir işaretçi sağlar.
Şöyle düşün: Jenerikler “T türüyle çalışırım” derken, trait nesneleri “bunu yapabilen her şeyle çalışırım” der. Bunun karşılığında, farklı türleri aynı değişken üzerinden ele alma esnekliği için küçük bir çalışma zamanı maliyeti ödenir.
Görev
KolayDinamik dağıtımın gücünü gösteren bir araç kiralama sistemi oluşturalım! Herhangi bir kiralanabilir aracın neler yapabileceğini tanımlayan bir trait oluşturacak, ardından farklı araç türlerini aynı değişkende saklamak için Box<dyn Trait> kullanacaksınız.
Kodunuzu iki dosyada düzenleyeceksiniz:
vehicle.rs: BirRentableyöntemini tanımlayan public birrental_infotrait'i oluşturun. Bu yöntem&selfalmalı ve birStringdöndürmelidir. Ardından iki public struct oluşturun:Car: public birmodelalanına (String) sahip olmalıdır.rental_infoyöntemiCar: {model}döndürmelidirBike: public birbrandalanına (String) sahip olmalıdır.rental_infoyöntemiBike: {brand}döndürmelidir
main.rs: vehicle modülünüzü dahil edin ve dinamik dağıtımı göstermek için girdileri kullanın. Önce birBox<dyn Rentable>tutan birCardeğişkeni oluşturun, kiralama bilgilerini yazdırın, ardından aynı değişkeni birBiketutacak şekilde yeniden atayın ve kiralama bilgilerini tekrar yazdırın.
Buradaki sihir, Box<dyn Rentable> türündeki tek bir değişkenin bir Car veya Bike tutabilmesidir: Rust çalışma zamanında hangi rental_info yönteminin çağrılacağını belirler. İşte dinamik dağıtım uygulamada böyle görünür!
Çıktınız her iki aracın da bilgilerini göstermelidir:
Car: {model}
Bike: {brand}Örneğin, girdiler Tesla Model 3 ve Trek olduğunda:
Car: Tesla Model 3
Bike: Trekİki girdi alacaksınız: araç modeli ve bisiklet markası.
Kendin dene
mod vehicle;
use vehicle::{Rentable, Car, Bike};
fn main() {
// Girdiyi oku
let mut car_model = String::new();
std::io::stdin().read_line(&mut car_model).expect("Failed to read line");
let car_model = car_model.trim().to_string();
let mut bike_brand = String::new();
std::io::stdin().read_line(&mut bike_brand).expect("Failed to read line");
let bike_brand = bike_brand.trim().to_string();
// TODO: Bir Car tutan Box<dyn Rentable> değişkeni oluştur
// rental_info() metodunu kullanarak kiralama bilgisini yazdır
// TODO: Aynı değişkeni bir Bike tutacak şekilde yeniden ata
// Kiralama bilgisini tekrar yazdır
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama 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 Player9Trait Nesneleri
Dinamik GönderimTrait VektörleriTrait Nesneleri Üzerinde YinelemeÖzet - Hayvanat Bahçesi YöneticisiKendi başına pratik yap: Online Rust derleyicisi