Dispatch Dinamis
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Rust di Coddy. Pelajaran 45 dari 61.
Saat kamu menggunakan generik dengan batas trait seperti <T: Summary>, Rust menentukan tipe yang tepat saat kompilasi. Ini disebut dispatch statis: compiler menghasilkan kode khusus untuk setiap tipe konkret yang kamu gunakan. Ini cepat, tetapi ada batasannya: sebuah variabel hanya dapat menyimpan satu tipe tertentu.
Bagaimana jika kamu membutuhkan satu variabel yang dapat menampung tipe yang berbeda saat program berjalan? Di sinilah trait object berperan. Dengan menggunakan Box<dyn Trait>, kamu dapat menyimpan tipe apa pun yang mengimplementasikan trait tersebut:
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!"
}
Kata kunci dyn menunjukkan dispatch dinamis: Rust mencari method yang akan dipanggil saat runtime, bukan saat compile time. Box diperlukan karena trait object tidak memiliki ukuran yang diketahui; Box menyediakan pointer dengan ukuran tetap.
Bayangkan seperti ini: generics menyatakan "Saya bekerja dengan tipe T," sedangkan trait object menyatakan "Saya bekerja dengan apa pun yang bisa melakukan ini." Komprominya adalah sedikit biaya runtime demi fleksibilitas dalam menangani berbagai tipe melalui variabel yang sama.
Tantangan
MudahMari buat sistem penyewaan kendaraan yang menunjukkan kehebatan dynamic dispatch! Kamu akan membuat trait yang menentukan hal-hal yang dapat dilakukan kendaraan apa pun yang bisa disewakan, lalu menggunakan Box<dyn Trait> untuk menyimpan berbagai tipe kendaraan dalam variabel yang sama.
Kamu akan mengatur kodemu dalam dua file:
vehicle.rs: Definisikan trait publikRentabledengan methodrental_infoyang menerima&selfdan mengembalikanString. Lalu buat dua struct publik:Car: dengan field publikmodel(String). Methodrental_infoharus mengembalikanCar: {model}Bike: dengan field publikbrand(String). Methodrental_infoharus mengembalikanBike: {brand}
main.rs: Gunakan module kendaraanmu dan manfaatkan input untuk menunjukkan dynamic dispatch. Buat variabelBox<dyn Rentable>yang awalnya menyimpanCar, cetak info penyewaannya, lalu tetapkan ulang variabel yang sama agar menyimpanBikedan cetak lagi info penyewaannya.
Keunggulannya adalah satu variabel bertipe Box<dyn Rentable> dapat menyimpan Car atau Bike: Rust menentukan method rental_info yang harus dipanggil saat program berjalan. Inilah dynamic dispatch!
Output-mu harus menampilkan informasi kedua kendaraan:
Car: {model}
Bike: {brand}Contohnya, dengan input Tesla Model 3 dan Trek:
Car: Tesla Model 3
Bike: TrekKamu akan menerima dua input: model mobil dan merek sepeda.
Coba sendiri
mod vehicle;
use vehicle::{Rentable, Car, Bike};
fn main() {
// Baca input
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: Buat variabel Box<dyn Rentable> yang menyimpan Car
// Tampilkan informasi sewanya menggunakan method rental_info()
// TODO: Isi ulang variabel yang sama agar menyimpan Bike
// Tampilkan lagi informasi sewanya
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Method dan Perilaku
Pengantar Blok ImplementasiParameter SelfMethod MutableFungsi TerkaitBeberapa Blok ImplementasiMethod BerantaiRangkuman: Aksi Persegi Panjang4Proyek: Hewan Peliharaan Virtual
Mendefinisikan Hewan PeliharaanMemberi Makan Hewan Peliharaan2Enkapsulasi dan module
Dasar-Dasar moduleKata Kunci publicField privateGetterSetterRekap: Loker AmanLatihan sendiri: Compiler Rust online