Mengiterasi Objek Trait
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Rust di Coddy. Pelajaran 47 dari 61.
Sekarang kamu bisa menyimpan berbagai tipe dalam Vec<Box<dyn Trait>>, langkah berikutnya adalah memproses koleksi tersebut. Melakukan iterasi pada trait object sama seperti melakukan iterasi pada vector apa pun. Kamu mengulangi setiap elemen dan memanggil method yang ditentukan oleh trait.
trait Shape {
fn area(&self) -> f64;
}
struct Circle { radius: f64 }
struct Rectangle { width: f64, height: f64 }
impl Shape for Circle {
fn area(&self) -> f64 { 3.14159 * self.radius * self.radius }
}
impl Shape for Rectangle {
fn area(&self) -> f64 { self.width * self.height }
}
fn main() {
let shapes: Vec<Box<dyn Shape>> = vec![
Box::new(Circle { radius: 2.0 }),
Box::new(Rectangle { width: 3.0, height: 4.0 }),
Box::new(Circle { radius: 1.0 }),
];
for shape in &shapes {
println!("Area: {}", shape.area());
}
}
Saat kamu melakukan iterasi dengan for shape in &shapes, setiap shape adalah referensi ke Box<dyn Shape>. Kamu bisa memanggil method apa pun dari trait Shape secara langsung: Rust menangani dispatch dinamis secara otomatis, dengan memanggil implementasi yang tepat untuk setiap tipe konkret.
Pola ini sangat berguna untuk menggabungkan hasil. Kamu bisa menjumlahkan semua luas, memfilter bentuk berdasarkan ukuran, atau mengubah koleksinya. Intinya, setelah item berada dalam koleksi trait object, kamu berinteraksi dengannya hanya melalui antarmuka trait, terlepas dari tipe yang mendasarinya.
Tantangan
MudahMari kita buat kalkulator harga untuk keranjang belanja yang dapat menampung berbagai jenis item! Kamu akan membuat sistem tempat produk dan layanan, masing-masing dengan logika penetapan harga yang berbeda, dapat disimpan bersama dan diproses untuk menghitung total harga.
Kamu akan menyusun kodemu dalam dua file:
items.rs: Definisikan trait publikPriceabledengan methodpriceyang menerima&selfdan mengembalikanf64. Lalu, buat dua struct publik:Product: dengan field publikname(String) dancost(f64). Methodprice-nya harus langsung mengembalikancost.Service: dengan field publikname(String),hourly_rate(f64), danhours(f64). Methodprice-nya harus mengembalikanhourly_rate * hours.
main.rs: Masukkan module items dan buat vector bertipeVec<Box<dyn Priceable>>. Gunakan input untuk membuat satu Product dan satu Service, tambahkan keduanya ke vector, lalu lakukan iterasi pada koleksi untuk menghitung dan mencetak total harga semua item.
Keunggulan trait object terlihat di sini. Kode iterasimu tidak perlu mengetahui apakah kode sedang memproses Product atau Service. Kode cukup memanggil price() pada setiap item, dan Rust akan otomatis memilih implementasi yang tepat.
Output-mu harus menampilkan total harga dengan dua angka desimal:
Total: ${total}Contohnya, dengan input Laptop, 999.99, Consulting, 150.0, dan 3.0:
Total: $1449.99Dan dengan input Book, 29.99, Tutoring, 50.0, dan 2.0:
Total: $129.99Kamu akan menerima lima input: nama produk, biaya produk, nama layanan, tarif per jam, dan jumlah jam kerja (parse nilai numerik sebagai f64).
Coba sendiri
mod items;
use items::{Priceable, Product, Service};
fn main() {
// Baca input
let mut product_name = String::new();
std::io::stdin().read_line(&mut product_name).expect("Failed to read line");
let product_name = product_name.trim().to_string();
let mut product_cost = String::new();
std::io::stdin().read_line(&mut product_cost).expect("Failed to read line");
let product_cost: f64 = product_cost.trim().parse().expect("Failed to parse");
let mut service_name = String::new();
std::io::stdin().read_line(&mut service_name).expect("Failed to read line");
let service_name = service_name.trim().to_string();
let mut hourly_rate = String::new();
std::io::stdin().read_line(&mut hourly_rate).expect("Failed to read line");
let hourly_rate: f64 = hourly_rate.trim().parse().expect("Failed to parse");
let mut hours = String::new();
std::io::stdin().read_line(&mut hours).expect("Failed to read line");
let hours: f64 = hours.trim().parse().expect("Failed to parse");
// TODO: Buat Product menggunakan product_name dan product_cost
// TODO: Buat Service menggunakan service_name, hourly_rate, dan hours
// TODO: Buat Vec<Box<dyn Priceable>> dan tambahkan kedua item ke dalamnya
// TODO: Telusuri setiap elemen vektor dan hitung harga totalnya
// TODO: Tampilkan total dengan satu angka di belakang koma
// Format: Total: ${total:.1}
}
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