Learning Rust and Lemmy
maegul
•
6mo ago
•
96%
TIL: All let statements use patterns [RUST]
A minor but interesting and illuminating point came up in a conversation that I thought was worth sharing, for those learning rust, in a separate post. I'm mostly just copy-and-pasting here.
- See comment here by @Ephera@lemmy.ml
TL;DR: The patterns you use in match
statements and related syntax are (basically) available to you in let
statements. This is how destructuring works!! And what they're for with let
. But the patterns have to be "irrefutable" --- IE, they have to always be able to match the expression/value.
For those who aren't aware, here's the first section in The Book on patterns in let
statements.
I think, if this is confusing, there are two points of clarification:
- All
let
statements involve patterns (as Ephera states). They're alllet PATTERN = EXPRESSION
.- For ordinary variable binding, we're just providing a basic pattern that is essentially like a wildcard in that it will match the totality of any expression and so be bound to the full/final value of that expression.
- It's only when the pattern becomes more complex that the pattern matching part becomes evident, as elements of the value/expression are destructured into those of the pattern.
- EG,
let (x, y, _) = (1, 2, 3);
or Ephera's example belowlet Something(different_thing) = something;
which extracts the single field of thestruct
something
into the variabledifferent_thing
(handy!).
let
statements must useirrefutable
patterns. That is, patterns that cannot fail to match the expression.- For example, against a tuple,
(x, y, _)
will always match. Another way of putting it:irrefutable
patterns are about destructuring not testing or conditional logic. if let
statements on the other hand can take bothirrefutable
patterns andrefutable
, but are really intended to be used withrefutable
patterns as they're intended for conditional logic where the pattern must be able to fail to match the expression/value.- See The Book chapter on
refutability
- For example, against a tuple,
The nice and useful example provided by @Ephera@lemmy.ml (in the original comment):
struct Something(DifferentThing);
let something = Something(DifferentThing::new());
let Something(different_thing) = something;
- Here, the variable
something
is astruct
of typeSomething
which contains one field of typeDifferentThing
. - In the final line, we're extracting that
DifferentThing
field with a pattern in alet
statement. - IE,
Something(different_thing)
is the pattern. And it is irrefutable against all variables of typeSomething
, as they have only one field.
Comments 2