Skip to content

Irrefutable patterns

Level: 101 → 201 · for newcomers

One line: The left of every let is a pattern, not a name — let x = 5; is the simplest one there is — and the rule that decides where a pattern is allowed is whether it can fail: let (a, b) = pair; always fits, let Some(n) = opt; might not, and only the first is legal in a plain let.

Stub — an outline, not a lesson. There is no runnable example behind this page yet, so nothing on it has been through the check that backs every other claim in this library. The bullets below are the questions the finished page has to answer.

What it has to cover

  • Irrefutable = cannot fail to match. A bare name, a tuple, a struct, _. Refutable = might not fit: any enum variant, any literal, any range
  • The four places that demand an irrefutable pattern — let, for loop bindings, function parameters, closure parameters — and why: there is no second branch for the failure to go to
  • The four that accept a refutable one — match arms, if let, while let, let else — because each supplies that branch
  • fn print_pair((a, b): (i32, i32)) and for (i, name) in names.iter().enumerate() are pattern matching, and reading them that way is the point of the page
  • E0005 and what its "refutable pattern in local binding" message is actually telling you to do
  • _ versus _name, which are different, and only one of them is a pattern that binds

The trap it exists for

let Some(n) = opt; is the natural thing to write and it does not compile. Every beginner writes it, reads E0005, and reaches for .unwrap() — which works and throws away the branch that made the pattern refutable in the first place. The right fixes are if let, let else, or a match, and which of the three depends on what should happen when it does not fit.

See also

Po polsku

Po lewej stronie każdego let stoi wzorzec (pattern), a nie nazwa — let x = 5; to po prostu najprostszy z możliwych. Gdy się to raz zobaczy, fn wypisz((a, b): (i32, i32)) i for (i, nazwa) in nazwy.iter().enumerate() przestają być osobnymi ciekawostkami składniowymi i okazują się tym samym dopasowaniem wzorców, które znasz z match.

Rozstrzyga jedno pytanie: czy wzorzec może nie pasować. Wzorzec niepodważalny (irrefutable) pasuje zawsze — gołe nazwy, krotki, struktury, _. Wzorzec podważalny (refutable) może nie pasować: każdy wariant wyliczenia, każdy literał, każdy zakres. Cztery miejsca żądają niepodważalnego — let, wiązania w for, parametry funkcji i domknięć — bo nie mają dokąd skierować niepowodzenia. Cztery przyjmują podważalny — ramiona match, if let, while let, let else — bo każde z nich taką gałąź dostarcza.

Stąd pułapka, którą pisze każdy początkujący: let Some(n) = opt; się nie kompiluje. Odruchem po przeczytaniu E0005 jest .unwrap() — działa i wyrzuca dokładnie tę gałąź, przez którą wzorzec był podważalny. Właściwe wyjścia to if let, let else albo match, a wybór między nimi zależy wyłącznie od tego, co ma się stać, gdy wzorzec nie pasuje.

Szukaj po polsku: wzorce niepodważalne i podważalne · dopasowanie wzorców · rust refutable pattern · E0005