I wrote something like:
enum E {
A,
B,
C,
}
fn foo(v: Option<E>) {
if let Some(A) = v {} else {
// stmts
}
}
Maybe we can provide a syntax sugar like if let pat != v { ... }
?
I wrote something like:
enum E {
A,
B,
C,
}
fn foo(v: Option<E>) {
if let Some(A) = v {} else {
// stmts
}
}
Maybe we can provide a syntax sugar like if let pat != v { ... }
?
May not be sugary enough for you but you can write if !matches!(v, Some(A)) {…}
.
Due to the slightly confusing appearance of the two exclamation marks around matches
I might personally write this as
if !(matches!(v, Some(A))) {…}
with some extra parentheses.
There's always:
use std::ops::Not as _;
if matches!(v, Some(A)).not() {
// ...
}
I mean why not just use let-else
. It was introduced specifically for this purpose and stabilised in 1.65.0.
let Some(A) = v else {
// ... do smthing
}
println!("{A}");
let-else always needs to diverge in the else block. This might not be ergonomic in some cases.
This behavior could fully be resolved by feature which is called Not-pattern. It looks like that:
Pattern : NotPattern | PatternNoTopAlt
NotPattern : not PatternNoTopAlt
And examples:
if let not Some ( 5 ) = foo () {
bar ()
}
let x = if let not 1 .. 8 = foo () { /* */ };
It's far from ergonomic, but you can build this from let-else, e.g.
'label: {
let Some(5) = foo() else {
bar();
break 'label;
}
}
but truthfully I'd say if you don't want it to make any bindings (and thus require the else to diverge), just write it as
if matches!(foo(), Some(5)) == false {
bar();
}
and be done with it. Clippy doesn't like it and wants !matches!
instead, but clippy can be quieted, or you can import ops::Not
and use .not()
instead if you do this a lot.
This form is almost entirely useless, since value if-let must have an else, so it's just the difference
// between
let x = if let 1..8 = foo() { positive() } else { negative() };
// and
let x = if let not 1..8 = foo() { negative() } else { positive() };
and no more.
let-else was significant enough to be added because creating a refutable binding in the same scope is a reasonably common operation with a meaningful restriction to make it possible. let-else-match allowing you to recover the residual of the scrutinee might pass the significance bar. Not patterns almost certainly won't. People already aren't particularly fond of using [if-]let[-else] with bindless patterns, and a not pattern must be bindless by necessity.
On average, code doing this a lot is likely structured suboptimally, and could benefit from more specific types and/or parsing rather than validating.
Designing a language solution has never been the hard part here; the hard part is showing that the problem is significant enough to deserve a solution to be added to the language.
I would just write:
if !matches!(...)
For better or worse, Rust has decided to use !
for two different things: embrace it and enjoy the slightly funny notation.
This is neither serious, nor a technical contribution, nor helpful in any way... but...
This prefix-negated matches
in isolation reminds me of the "opening exclamation point" used in Spanish:
if ¡matches!(...)
And for those who really strongly care about not having to write !matches!(...)
, there is always
use std::ops::Not;
matches!(...).not()
Though for me personally, that's a bit much.
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.