Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Çürütülebilirlik: Bir Desenin Eşleşememe İhtimali

Desenler iki ana biçime ayrılır: çürütülebilir ve çürütülemez. Her olası değerle eşleşen desenlere çürütülemez denir. Örneğin let x = 5; ifadesindeki x böyledir; çünkü her şeyle eşleşir. Bazı olası değerlerde eşleşmesi başarısız olabilen desenler ise _çürütülebilir_desendir. Örneğin if let Some(x) = bir_deger ifadesindeki Some(x) böyledir; çünkü değer None olursa desen eşleşmez.

Fonksiyon parametreleri, let ifadeleri ve for döngüleri yalnızca çürütülemez desen kabul eder. Çünkü eşleşme başarısız olduğunda programın o bağlamda anlamlı biçimde ne yapacağı belli değildir. if let, while let ve let...else ise çürütülebilir desenlerle çalışmak için tasarlanmıştır.

Genelde bu ayrımı düşünmeniz gerekmez. Ama hata mesajlarında çürütülebilirlik karşınıza çıkınca, ya deseni ya da onu kullandığınız yapıyı değiştirmeniz gerektiğini anlamanız önemlidir.

Önce, çürütülebilir bir deseni let içinde kullanmaya çalıştığımız bir örneğe bakalım. 19-8 numaralı liste bunu gösteriyor.

fn main() {
    let bir_secenek_degeri: Option<i32> = None;
    let Some(x) = bir_secenek_degeri;
}
Listing 19-8: let ile çürütülebilir desen kullanmaya çalışmak

Eğer bir_secenek_degeri, Some yerine None olsaydı, Some(x) deseni eşleşemezdi. Ama let yalnızca çürütülemez desen kabul ettiği için derleyici hata verir:

    Checking desenler v0.1.0 (/home/hakanbiris/github/kitap/listings/ch19-patterns-and-matching/listing-19-08)
error[E0005]: refutable pattern in local binding
 --> src/main.rs:4:9
  |
4 |     let Some(x) = bir_secenek_degeri;
  |         ^^^^^^^ pattern `None` not covered
  |
  = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
  = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
  = note: the matched value is of type `Option<i32>`
help: you might want to use `let...else` to handle the variant that isn't matched
  |
4 |     let Some(x) = bir_secenek_degeri else { todo!() };
  |                                      ++++++++++++++++

For more information about this error, try `rustc --explain E0005`.
error: could not compile `desenler` (bin "desenler") due to 1 previous error

Sorun, Some(x) deseninin bütün olasılıkları kapsamamasıdır.

Eğer çürütülebilir bir desene gerçekten ihtiyacımız varsa, let yerine let...else kullanabiliriz. Böylece desen eşleşmezse süslü parantez içindeki kod çalışır. 19-9 numaralı liste bunu gösteriyor.

fn main() {
    let bir_secenek_degeri: Option<i32> = None;
    let Some(x) = bir_secenek_degeri else {
        return;
    };
}
Listing 19-9: Çürütülebilir desenlerde let yerine let...else kullanmak

Bu biçimde desene bir çıkış yolu vermiş oluruz; desen eşleşmezse else kolundaki kod devreye girer.

Ama bu kez de ters durum mümkündür: let...else içine zaten her zaman eşleşecek bir desen koyarsanız, derleyici bunun anlamsız olduğunu söyler. 19-10 numaralı liste buna örnek:

fn main() {
    let x = 5 else {
        return;
    };
}
Listing 19-10: let...else ile çürütülemez desen kullanmaya çalışmak

Burada desen her zaman başarılı olduğu için else kolunun hiçbir anlamı kalmaz ve Rust uyarı verir:

warning: irrefutable `let...else` pattern
 --> src/main.rs:3:5
  |
3 |     let x = 5 else {
  |     ^^^^^^^^^
  |
  = note: this pattern will always match, so the `else` clause is useless
  = help: consider removing the `else` clause
  = note: `#[warn(irrefutable_let_patterns)]` on by default

warning: unused variable: `x`
 --> src/main.rs:3:9
  |
3 |     let x = 5 else {
  |         ^ help: if this is intentional, prefix it with an underscore: `_x`
  |
  = note: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default

warning: `desenler` (bin "desenler") generated 2 warnings (run `cargo fix --bin "desenler" -p desenler` to apply 1 suggestion)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s

Bu nedenle match kolları genelde çürütülebilir desenler kullanır; son kol ise genellikle kalan her şeyi yakalayan çürütülemez bir desen olur.

Artık desenlerin nerede kullanılabileceğini ve çürütülebilirlik ayrımını gördük. Sırada, desen oluştururken kullanabileceğimiz sözdizimlerinin tamamı var.