Menu
Coddy logo textTech

Trait Nesneleri Üzerinde Yineleme

Coddy'nin Rust Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 47 / 61.

Artık bir Vec<Box<dyn Trait>> içinde farklı türleri saklayabildiğinize göre, bir sonraki adım bu koleksiyonu işlemektir. Trait nesneleri üzerinde yineleme yapmak, herhangi bir vektör üzerinde yineleme yapmakla aynı şekilde çalışır; her bir öğe üzerinde döngü kurar ve trait tarafından tanımlanan metotları çağırırsınız.

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());
    }
}

for shape in &shapes ile yineleme yaptığınızda, her bir shape bir Box<dyn Shape> referansıdır. Shape trait'inden herhangi bir metodu doğrudan çağırabilirsiniz; Rust, dinamik gönderimi (dynamic dispatch) otomatik olarak yöneterek her bir somut tür için doğru uygulamayı çağırır.

Bu desen, sonuçları bir araya getirmek için güçlüdür. Tüm alanları toplayabilir, şekilleri boyutlarına göre filtreleyebilir veya koleksiyonu dönüştürebilirsiniz. Buradaki temel içgörü, öğeler bir trait nesnesi koleksiyonuna girdikten sonra, temel tiplerinden bağımsız olarak onlarla tamamen trait'in arayüzü üzerinden etkileşime girmenizdir.

challenge icon

Görev

Kolay

Farklı türdeki öğeleri tutabilen bir alışveriş sepeti için bir fiyat hesaplayıcı oluşturalım! Her biri farklı fiyatlandırma mantığına sahip ürünlerin ve hizmetlerin bir arada saklanabileceği ve toplam fiyatı hesaplamak için işlenebileceği bir sistem oluşturacaksınız.

Kodunuzu iki dosya halinde düzenleyeceksiniz:

  • items.rs: &self alan ve f64 döndüren bir price metoduna sahip, genel (public) bir Priceable trait'i tanımlayın. Ardından iki genel struct oluşturun:
    • Product — genel name (String) ve cost (f64) alanlarına sahip. price metodu sadece cost değerini döndürmelidir.
    • Service — genel name (String), hourly_rate (f64) ve hours (f64) alanlarına sahip. price metodu hourly_rate * hours değerini döndürmelidir.
  • main.rs: items modülünüzü dahil edin ve Vec<Box<dyn Priceable>> tipinde bir vektör oluşturun. Girdileri kullanarak bir Product ve bir Service oluşturun, bunları vektörünüze ekleyin, ardından tüm öğelerin toplam fiyatını hesaplamak ve yazdırmak için koleksiyon üzerinde döngü kurun.

Trait nesnelerinin gücü burada parlıyor; döngü kodunuzun bir Product mı yoksa bir Service mi işlediğini bilmesine gerek yoktur. Sadece her öğe üzerinde price() metodunu çağırır ve Rust otomatik olarak doğru uygulamaya yönlendirir.

Çıktınız toplam fiyatı bir ondalık basamakla göstermelidir (Not: Çözüm kodunda "Total: ${:.1}" formatı kullanılmıştır):

Total: ${total}

Örneğin, Laptop, 999.99, Consulting, 150.0 ve 3.0 girdileriyle:

Total: $1450.0

Ve Book, 29.99, Tutoring, 50.0 ve 2.0 girdileriyle:

Total: $130.0

Beş girdi alacaksınız: ürün adı, ürün maliyeti, hizmet adı, saatlik ücret ve çalışılan saat (sayısal değerleri f64 olarak ayrıştırın).

Kendin dene

mod items;

use items::{Priceable, Product, Service};

fn main() {
    // Girdileri oku
    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: product_name ve product_cost kullanarak bir Product oluşturun

    // TODO: service_name, hourly_rate ve hours kullanarak bir Service oluşturun

    // TODO: Bir Vec<Box<dyn Priceable>> oluşturun ve her iki öğeyi de buna ekleyin

    // TODO: Vektör üzerinde döngü kurun ve toplam fiyatı hesaplayın

    // TODO: Toplamı bir ondalık basamakla yazdırın
    // Format: Total: ${total:.1}
}
quiz iconKendini test et

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