Menu
CoddyTech

Dispatch Dinamis

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Rust di Coddy. Pelajaran 45 dari 61.

Saat kamu menggunakan generics dengan batasan trait seperti <T: Summary>, Rust menentukan tipe yang tepat saat kompilasi. Ini disebut static dispatch: compiler menghasilkan kode khusus untuk setiap tipe konkret yang kamu gunakan. Proses ini cepat, tetapi ada batasannya: satu variabel hanya bisa menyimpan satu tipe tertentu.

Bagaimana jika kamu memerlukan satu variabel yang dapat menyimpan 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 kompilasi. Box diperlukan karena ukuran trait object tidak diketahui; Box menyediakan pointer dengan ukuran tetap.

Bayangkan seperti ini: generics berarti "Saya bekerja dengan tipe T," sedangkan trait object berarti "Saya bekerja dengan apa pun yang bisa melakukan ini." Kompensasinya adalah sedikit biaya saat runtime demi fleksibilitas dalam menangani berbagai tipe melalui variabel yang sama.

challenge icon

Tantangan

Mudah

Mari kita buat sistem penyewaan kendaraan yang menunjukkan keunggulan dispatch dinamis! Kamu akan membuat trait yang menentukan hal-hal yang dapat dilakukan oleh 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 Rentable publik dengan method rental_info yang menerima &self dan mengembalikan String. Lalu buat dua struct publik:
    • Car: dengan field model publik (String). rental_info-nya harus mengembalikan Car: {model}
    • Bike: dengan field brand publik (String). rental_info-nya harus mengembalikan Bike: {brand}
  • main.rs: Sertakan module kendaraanmu dan gunakan input untuk menunjukkan dispatch dinamis. Buat variabel Box<dyn Rentable> yang awalnya menyimpan Car, cetak informasi penyewaannya, lalu tetapkan ulang variabel yang sama agar menyimpan Bike dan cetak kembali informasi penyewaannya.

Keunggulannya adalah satu variabel bertipe Box<dyn Rentable> dapat menyimpan Car atau Bike: Rust menentukan method rental_info mana yang harus dipanggil saat program berjalan. Inilah dispatch dinamis!

Output-mu harus menampilkan informasi kedua kendaraan:

Car: {model}
Bike: {brand}

Contohnya, dengan input Tesla Model 3 dan Trek:

Car: Tesla Model 3
Bike: Trek

Kamu 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 penyewaannya menggunakan method rental_info()
    
    // TODO: Isi kembali variabel yang sama dengan Bike
    // Tampilkan lagi informasi penyewaannya
    
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler Rust online