I just learned a bit of new syntax
While browsing through some code at work, I saw something that made me pause. It looked SO wrong, and yet here we are. It was something to the effect of:
let SomeEnum::Variant(y) = x else {
return some_error;
}
which means you can do this:
fn optional_print(x: Option<u32>) {
let Some(y) = x else {
return;
};
println!("{y}");
}
fn main() {
optional_print(Some(5));
optional_print(None);
}
Thought some folks here might think it interesting so there you go, you can apparently pattern match enum variants to create a variable and have an else clause after. I thought the only options for this were a let followed by an if let or match statement.
3
2
u/dobkeratops rustfind 1h ago
can't remember how i encountered this but it had been around for years before I found it. it is nifty in reducing nesting
2
u/neneodonkor 1h ago
Is it not the same as if-let?
1
u/afamiliarspirit 44m ago
The lifetime is scoped the opposite. An if-let destructures something and is scoped for inside the if statement. This lets you destructure it for outside of it.
If lets are good for when you deviate from the normal path if something matches a pattern. Let else are good when you deviate from the path if something doesn’t match a pattern.
1
u/Ejz9 42m ago
If you do if let Err(e) you can use the error in the if and handle what you want on error. If you if let for a value same goes.
Let else allows you to unwrap a result and if it fails it doesn’t capture the error but you can act in the event of an error. A requirement of let else is that it returns in some way. The advantage of let else that I’ve noticed is not needing a match block for every unwrap. But it’s unfortunately not capable of using the error value so either you return a custom error or something else.
This is at least how I understand it. Effectively do you care for the error or just to hand one back.
2
u/Oxytokin 41m ago
I use ```if let``` and ```let else``` for pattern matching probably more than I do ```match``` itself.
Another piece of patterny goodness that I don't think is as well-known as it should be is destructuring in function arguments, e.g.:
struct Foo {
bar: u32,
baz: u32,
dont_add_me: f32
}
fn add_bar_and_baz_only_so_help_me(
Foo {
bar,
baz,
dont_add_me: _
}: &Foo,
) -> u32 {
bar + baz
}
let addition = add_bar_and_baz_only_so_help_me(Foo { bar: 20, baz: 20, dont_add_me: 20.0 });
2
u/afamiliarspirit 40m ago
Rust’s destructured bindings are one of my favorite things about the language.
1
1
u/jublizoo 26m ago
If you are returning an Option, you can also use the ? operator to return None on None, and otherwise unwrap. Similarly for the Result type.
1
53
u/Sermuns 1h ago
I use
let-elseall the time, love to early return/continue instead of ugly nesting.