Menu
Coddy logo textTech

Veri Varyantlarını Eşleme

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

Önceki derste, farklı varyantları işlemek için enum metotları içinde match kullandınız. Şimdi match ifadesinin bu varyantların içinde saklanan veriyi gerçekte nasıl çıkardığına—destructuring (yapı bozma) adı verilen bir teknik—odaklanalım.

Veri tutan bir enum varyantı ile eşleşme yaptığınızda, bu veriyi doğrudan desen içinde değişkenlere bağlayabilirsiniz:

enum Event {
    Click { x: i32, y: i32 },
    KeyPress(char),
    Resize(u32, u32),
}

fn handle_event(event: Event) {
    match event {
        Event::Click { x, y } => {
            println!("Clicked at ({}, {})", x, y);
        }
        Event::KeyPress(key) => {
            println!("Key pressed: {}", key);
        }
        Event::Resize(width, height) => {
            println!("Resized to {}x{}", width, height);
        }
    }
}

Her bir kol, varyantın yapısına bağlı olarak verileri farklı şekilde çıkarır. Yapı benzeri (struct-like) varyantlar için, isimlendirilmiş alanları çekip çıkarmak için { field_name } kullanırsınız. Demet (tuple) varyantları için, (width, height) gibi konumsal değişkenler kullanırsınız.

Seçtiğiniz değişken isimleri o eşleşme kolunun (match arm) içinde kullanılabilir hale gelir. Bu güçlü bir özelliktir çünkü aynı anda hem hangi varyanta sahip olduğunuzu kontrol eder hem de onun verisine (payload) erişim sağlarsınız.

Derleyici, her varyantı ele almanızı sağlar ve çıkarılan değerler anında kullanıma hazırdır; ek bir adım gerekmez.

challenge icon

Görev

Kolay

Farklı türdeki kullanıcı komutlarını işleyen bir komut işlemcisi oluşturalım. Her komut farklı veriler taşır ve işlemciniz bu verileri ayıklamak ve uygun yanıtlar üretmek için desen eşleme (pattern matching) kullanacaktır.

Kodunuzu düzenlemek için iki dosya oluşturacaksınız:

  • command.rs: Üç varyantı olan genel bir Command enum'ı tanımlayın:
    • Say — tek bir String mesajı tutar (tuple sözdizimi)
    • Move — isimlendirilmiş alanlar tutar: direction (String) ve steps (u32)
    • Calculate — toplanacak sayıları temsil eden iki i32 değeri tutar (tuple sözdizimi)
    Ardından, her bir varyantı ayrıştırmak (destructure) için match kullanan ve gerçekleştirilen eylemi açıklayan bir String döndüren bir execute metodu uygulayın.
  • main.rs: Komut modülünüzü dahil edin, sağlanan girdileri kullanarak her komut varyantından birer örnek oluşturun ve sonuçları yazdırmak için her birinde execute metodunu çağırın.

execute metodunuz, verilerine erişmek için her varyantı ayrıştırmalı ve tam olarak şu formatlarda mesajlar döndürmelidir:

  • Say için: Saying: {message}
  • Move için: Moving {steps} steps {direction}
  • Calculate için: {a} + {b} = {sum}

Çıktınız, her komutun sonucunu kendi satırında görüntülemelidir:

Saying: {message}
Moving {steps} steps {direction}
{a} + {b} = {sum}

Örneğin, "Hello world" şeklinde bir say mesajı, "north" yönünde 5 adımlık bir move ve 10 ile 25 sayılarının hesaplanmasıyla çıktı şöyle olacaktır:

Saying: Hello world
Moving 5 steps north
10 + 25 = 35

Beş girdi alacaksınız: say mesajı, yön (direction), adım sayısı (steps) ve hesaplanacak iki sayı.

Kopya kağıdı

match ile desen eşleme (pattern matching), enum varyantlarını ayrıştırmanıza ve verilerini doğrudan desen içinde çıkarmanıza olanak tanır.

Demet (tuple) varyantları için konumsal değişkenler kullanın:

enum Event {
    KeyPress(char),
    Resize(u32, u32),
}

match event {
    Event::KeyPress(key) => {
        println!("Key: {}", key);
    }
    Event::Resize(width, height) => {
        println!("{}x{}", width, height);
    }
}

Yapı (struct) benzeri varyantlar için isimlendirilmiş alan sözdizimini kullanın:

enum Event {
    Click { x: i32, y: i32 },
}

match event {
    Event::Click { x, y } => {
        println!("Clicked at ({}, {})", x, y);
    }
}

Çıkarılan değişkenler, ilgili match kolu (arm) içinde kullanılabilir hale gelir; bu da varyant türünü kontrol etmenizi ve verilerine aynı anda erişmenizi sağlar.

Kendin dene

mod command;

use command::Command;

fn main() {
    // Girdileri oku
    let mut say_message = String::new();
    std::io::stdin().read_line(&mut say_message).expect("Failed to read line");
    let say_message = say_message.trim().to_string();

    let mut direction = String::new();
    std::io::stdin().read_line(&mut direction).expect("Failed to read line");
    let direction = direction.trim().to_string();

    let mut steps_input = String::new();
    std::io::stdin().read_line(&mut steps_input).expect("Failed to read line");
    let steps: u32 = steps_input.trim().parse().expect("Failed to parse steps");

    let mut num1_input = String::new();
    std::io::stdin().read_line(&mut num1_input).expect("Failed to read line");
    let num1: i32 = num1_input.trim().parse().expect("Failed to parse num1");

    let mut num2_input = String::new();
    std::io::stdin().read_line(&mut num2_input).expect("Failed to read line");
    let num2: i32 = num2_input.trim().parse().expect("Failed to parse num2");

    // TODO: say_message kullanarak bir Say komutu oluşturun ve çalıştırın
    
    // TODO: direction ve steps kullanarak bir Move komutu oluşturun ve çalıştırın
    
    // TODO: num1 ve num2 kullanarak bir Calculate komutu oluşturun ve çalıştırın
    
    // TODO: Her komut yürütmesinin sonuçlarını yazdırın
}
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