Değerleri Eşleştirmek

match anahtar kelimesi, bir değeri bir veya daha fazla desene (pattern) göre eşleştirmenizi sağlar. Desenler, C ve C++’daki switch’e benzer şekilde basit değerler olabilir, ancak daha karmaşık koşulları ifade etmek için de kullanılabilirler:

#[rustfmt::skip]
fn main() {
    let input = 'x';
    match input {
        'q'                       => println!("Çıkılıyor"),
        'a' | 's' | 'w' | 'd'     => println!("Etrafta hareket ediliyor"),
        '0'..='9'                 => println!("Sayı girişi"),
        key if key.is_lowercase() => println!("Küçük harf: {key}"),
        _                         => println!("Başka bir şey"),
    }
}

Desendeki bir değişken (bu örnekte key) eşleşme kolu (match arm) içinde kullanılabilecek bir bağlama (binding) oluşturacaktır. Bunu bir sonraki slaytta daha ayrıntılı öğreneceğiz.

Bir eşleşme filtresi (match guard), kolun yalnızca koşul doğruysa eşleşmesine neden olur. Koşul yanlışsa, eşleşme diğer durumları kontrol etmeye devam edecektir.

This slide should take about 10 minutes.

Önemli Noktalar:

  • Bir desendeyken bazı özel karakterlerin nasıl kullanıldığına dikkat edin

    • | bir veya (or) olarak
    • .. gerektiği kadar genişleyebilir
    • 1..=5 kapsayıcı bir aralığı (inclusive range) temsil eder
    • _ bir joker karakterdir
  • Ayrı bir sözdizimi özelliği olarak eşleşme filtreleri (match guards), tek başına desenlerin izin verdiğinden daha karmaşık fikirleri kısaca ifade etmek istediğimizde önemli ve gereklidir.

  • Match guards are different from if expressions after the =>. An if expression is evaluated after the match arm is selected. Failing the if condition inside of that block won’t result in other arms of the original match expression being considered. In the following example, the wildcard pattern _ => is never even attempted.

#[rustfmt::skip]
fn main() {
    let input = 'a';
    match input {
        key if key.is_uppercase() => println!("Uppercase"),
        key => if input == 'q' { println!("Çıkılıyor") },
        _   => println!("Bug: this is never printed"),
    }
}
  • Filtrede tanımlanan koşul, bir | içeren bir desendeki her ifade için geçerlidir.

  • Bir eşleşme kolunda (match arm) mevcut bir değişkeni koşul olarak kullanamayacağınızı unutmayın, çünkü bunun yerine bir değişken adı deseni (variable name pattern) olarak yorumlanacaktır, bu da mevcut olanı gölgeleyecek (shadow) yeni bir değişken oluşturur. Örneğin:

    #![allow(unused)]
    fn main() {
    let expected = 5;
    match 123 {
        expected => println!("Beklenen değer 5, gerçek değer {expected}"),
        _ => println!("Değer başka bir şeydi"),
    }
    }

    Burada 123 sayısıyla eşleştirmeye çalışıyoruz, ilk durumun değerin 5 olup olmadığını kontrol etmesini istiyoruz. Doğal beklenti, değer 5 olmadığı için ilk durumun eşleşmeyeceğidir, ancak bunun yerine bu, her zaman eşleşen bir değişken deseni olarak yorumlanır, yani her zaman ilk dal alınacaktır. Bunun yerine bir sabit (constant) kullanılırsa bu beklendiği gibi çalışacaktır.

Daha Fazlasını Keşfedin

  • Öğrencilere gösterebileceğiniz başka bir desen sözdizimi parçası, bir desenin bir bölümünü bir değişkene bağlayan @ sözdizimidir. Örneğin:

    #![allow(unused)]
    fn main() {
    let opt = Some(123);
    match opt {
        outer @ Some(inner) => {
            println!("dış: {outer:?}, iç: {inner}");
        }
        None => {}
    }
    }

    Bu örnekte inner, çözümleme (destructuring) yoluyla Option’dan çektiği 123 değerine sahiptir, outer ise tüm Some(inner) ifadesini yakalar, bu nedenle tam Option::Some(123)’ü içerir. Bu nadiren kullanılır ancak daha karmaşık desenlerde faydalı olabilir.