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
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.@ile aralık bağlama:n @ 1..=12ifadesi iki işi aynı anda yapar.1..=12aralığı değerin bu aralıkta olmasını şart koşar;nise eşleşen değerin kendisini kollar. Alt kol, değeri tekrar hesaplamadannüzerinden kullanabilir:"I'm a child of age {:?}", n. Bu, özelliklematches!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.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 öncekin @ 1..=12ven @ 13..=19kolları tarafından kapsanmaktadır. Bu nedenle derleyiciunreachable_patternsuyarı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:matchkolları sırayla denendiğinden, önceki kolların kapsadığı değerler sonraki kollar için ölü koddur.Yakalayıcı joker kol: Son
n => ...kolu hem "her şey" deseninin görevini görür hem de kalan tüm değerlerin'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
İç içe desen eşleştirme:
Some(n @ 42)deseni,Option'ınSomevaryantını seçer ve içindeki değer üzerinde ikinci bir eşleştirme yapar:n @ 42. Değer 42 ise eşleşir ven'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.Kısmi bağlama:
Some(n)kolu,Someiçindeki her değeri yakalar ven'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._ => ():Nonevaryantı 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:
- Değerin bir aralıkta olmasını isteyip yine de değerin kendisini kullanmak istiyorsanız:
n @ 1..=12 - Değerin enum içindeki belirli bir sabit olmasını isteyip iç değeri yakalamak istiyorsanız:
Some(n @ 42)
@'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.