gokayburuc

Rust - Match Value Binding

Rust'ta match ile Değer Bağlama: Aralık ve Enum Desenleri

Giriş

Rust'ın match ifadesi, güçlü desen eşleştirmesinin (pattern matching) ötesinde bir yetenek daha sunar: eşleşen değeri bir değişkene bağlama. @ operatörü ile birlikte kullanılan bu özellik, hem değerin yapısını test etmeyi hem de değerin kendisini yakalamayı aynı anda mümkün kılar. Bu makale, aralık tabanlı bağlamayı ve Option gibi enum tipleri üzerinde bağlama yapmayı örnek kodlar üzerinden incelemektedir.

Aralık ve Sabit Desenlerinde Bağlama

Örnek Kod

fn age() -> u32 {
    15
}

#[allow(unreachable_patterns)]
pub fn execute_binding() {
    println!("Tell me what type of person you are");

    match age() {
        0 => println!("I havent celebrated my first birthday yet"),
        n @ 1..=12 => println!("I'm a child of age {:?}", n),
        n @ 13..=19 => println!("I'm a teen of age {:?}", n),

        // WARN: this is unreachable
        n @ (1 | 7 | 15 | 13) => println!("I'm a teen of age {:?}", n),
        n => println!("I'm an old person of age {:?}", n),
    }
}

Çıktı

Tell me what type of person you are
I'm a teen of age 15

Adım Adım Analiz

  1. Sabit deseni: 0 => ... kolu, değerin bire bir sıfıra eşit olduğu tek bir durumu yakalar. Sabit desenlerde bağlamaya gerek yoktur; değer zaten bilinmektedir.

  2. @ ile aralık bağlama: n @ 1..=12 ifadesi iki işi aynı anda yapar. 1..=12 aralığı değerin bu aralıkta olmasını şart koşar; n ise eşleşen değerin kendisini kollar. Alt kol, değeri tekrar hesaplamadan n üzerinden kullanabilir: "I'm a child of age {:?}", n. Bu, özellikle matches! gibi yardımcılar olmadan değerin hem sınıflandırılmasını hem de kullanılmasını gerektiren durumlarda kısa ve net bir çözümdür.

  3. Ulaşılamayan kol ve #[allow]: Dördüncü kol dikkat çekicidir: n @ (1 | 7 | 15 | 13). Bu kolun eşleştiği tüm değerler (1, 7, 13, 15) zaten önceki n @ 1..=12 ve n @ 13..=19 kolları tarafından kapsanmaktadır. Bu nedenle derleyici unreachable_patterns uyarısı verir; örnek bu uyarıyı bilinçli olarak bastırmak için #[allow(unreachable_patterns)] niteliğini taşır. Bu, Rust derleyicisinin desen kapsamını statik olarak çözümleyebildiğinin kanıtıdır: match kolları sırayla denendiğinden, önceki kolların kapsadığı değerler sonraki kollar için ölü koddur.

  4. Yakalayıcı joker kol: Son n => ... kolu hem "her şey" deseninin görevini görür hem de kalan tüm değerleri n'e bağlar. Klasik _ => ... deseninden farkı, değerin yakalanıyor olmasıdır.

Enum Desenlerinde Bağlama: Option Örneği

Örnek Kod

fn some_number() -> Option<u32> {
    Some(42)
}

pub fn execute_enum_binding() {
    match some_number() {
        Some(n @ 42) => println!("The Answer: {}!", n),
        Some(n) => println!("Not interesting... {}", n),
        _ => (),
    }
}

Çıktı

The Answer: 42!

Adım Adım Analiz

  1. İç içe desen eşleştirme: Some(n @ 42) deseni, Option'ın Some varyantını seçer ve içindeki değer üzerinde ikinci bir eşleştirme yapar: n @ 42. Değer 42 ise eşleşir ve n'e bağlanır. @ operatörü, enum yapısının içindeki değerlere de uygulanabilir; bu da onu yalnızca üst düzey değerler için değil, katmanlı veri yapıları için de kullanışlı kılar.

  2. Kısmi bağlama: Some(n) kolu, Some içindeki her değeri yakalar ve n'e bağlar. Bu kol 42'yi de kapsardı; ancak önceki kol sıralama gereği 42'yi zaten ele aldığından buraya yalnızca "ilgi çekici olmayan" değerler düşer.

  3. _ => (): None varyantı bu kole gelir. Değer yoktur, bağlanacak bir şey de yoktur; dolayısıyla boş işlem () döndürülür. Bu, match'in tüketici (exhaustive) olma zorunluluğunun en ekonomik karşılanışıdır: hiçbir varyant ele alınmadan bırakılamaz.

@ Operatörünün Anlamı

Her iki örnek de aynı mekaniği farklı veri tiplerinde gösterir:

@'sız yazılan 42 => ... deseninde değere erişim zaten mümkün değildir (desen yalnızca bir karşılaştırmadır); n @ 42 ise karşılaştırmayı ve bağlamayı birleştirir. Bu ayrım, Rust desen dilinin bileşik (compositional) yapısını örnekler: aralar, varyant seçicileri ve bağlamalar iç içe yerleştirilebilir.

Sonuç

@ operatörü, Rust desen eşleştirmesinde "eşleş ve yakala" ihtiyacını tek ifadede çözer. Aralık desenlerinde değerin sınıflandırılmasını kullanılabilir bir bağla birlikte sunar; enum desenlerinde ise yapısal seçimin içine değer düzeyinde koşul yerleştirir. Örneklerin gösterdiği gibi, match kolları sıralı ve tüketicidir: erken kolların kapsadığı durumlar sonraki kollar için ölüdür ve derleyici bunu statik olarak tespit edebilir. Bu özelliklerin birleşimi, dallanma mantığını derleyicinin doğrulayabildiği, if-else zincirlerinden çok daha güvenli bir biçime dönüştürür.

#rust