4 ms·
For me, a feature I'd really hope for is the elusive "if not let" (or however this gets named eventually), to let me escape the currently unavoidable clutches o
by akavel 6y ago
For me, a feature I'd really hope for is the elusive "if not let" (or however this gets named eventually), to let me escape the currently unavoidable clutches of Rust's rightwards drift and accruing mental context.
- yazaddaruvala 6y agoLol it would be kinda funny to have this: let input: Option<usize> = Some(1); if let Some(value) != input { return 0; } // use value; such that value: usize = 1
- nybble41 6y agoWe already have something close: let input: Option<usize> = Some(1); let value = match input { Some(x) => x, _ => return 0, }; // use value; such that value: usize = 1
- NobodyNada 6y agoThat works, but it's clunky enough that it defeats the purpose of writing guard statements IMO. It's not hard to understand, but it's also not possible to figure out what it means at-a-glance. I have to stare at it for a few seconds to try to figure out where all control flow is going to go -- it has two levels of nested subexpressions, along with branches that appear similar but do very different things (returning a value from the expression vs. from the function). The point of a 'guard' clause is to visually distinguish between the "expected" and "unexpected" case. When I see a guard statement: let input: Option<usize> = Some(1); guard let Some(value) = input else { return 0; } // use value; such that value: usize = 1 I immediately know that the rest of the function expects input to contain a value, and that whatever is after the 'else' is some kind of error handler. Your match statement might have the same effect functionally, but visually it's confusing because it's not immediately obvious which branch is the happy-path. I'd rather read a function containing ten guard clauses than a function containing ten of those matches.
- freeopinion 6y agoSome(1).unwrap_or(0)
- Quekid5 6y agoReturn 0 is different from using 0 in the rest of the function body.
- NobodyNada 6y agoSwift has had ‘guard’ statements since 2015, and it’s the biggest thing I miss when programming in Rust: guard let x = ... else { // must not fall through, so a return, break, throw, non-returning function call, etc. is required } // do something with x
- kibwen 6y agoIn Rust I would just do: let x = match foo { Some(x) => ..., None => return // or break, etc. }; // do something with x (This is assuming that you don't want to propagate an error or panic, which could be more easily done with `foo?` or `foo.unwrap()` respectively.)
- emptysea 6y agoA nice quality of the `guard` in swift is that you can chain multiple conditions, which is harder to do in rust (maybe with some macros a la if_chain?)
- safarimonkey 6y agoI ran into this the other day, and it took me a moment to realise that I could just use `matches!`: // want to do this if not let Some("pattern") = val { doSomething(); } // can instead do if !matches!(val, Some("pattern")) { doSomething(); }
- NobodyNada 6y agoThat won’t allow extracting a value from the optional though, will it? i.e. I can’t do this something along the lines of: if !matches!(val, Some(let x))
- safarimonkey 6y agoIndeed not, so it's not a full replacement. I'm not entirely sure that I like the idea of an "if let" variant creating bindings that escape the visual block, but I'd probably get over it.
- rwxsh 6y agoRust has this, it's `let ... = match { ... };`.