4 ms·
One thing Rust doesn't seem to be doing very well yet is guard clauses, specifically when handling Option<T>. I've seen and appreciated the use of guard clause
by vmarsy 8y ago
One thing Rust doesn't seem to be doing very well yet is guard clauses, specifically when handling Option<T>.
I've seen and appreciated the use of guard clauses in many languages, as a good way to quickly check for a few conditions at the top of a function, and return early if those conditions aren't met.
Since it seems that Option<T> are recommended in Rust, there's a lot of time you want to quickly return if `Some(x)` is not here (i.e. it's `None`), and if it's here, continue through the function, without having an unnecessary indentation from an extra brackets.
There seem to be a good amount of smart discussion into handling those [1][2]. some threads are more than a year old, but it seems to be making progress.
[1] https://github.com/rust-lang/rust/issues/45978 https://github.com/rust-lang/rust/issues/45978
[2] https://internals.rust-lang.org/t/pre-rfc-allow-pattern-matching-after-guard-clause/6238 https://internals.rust-lang.org/t/pre-rfc-allow-pattern-matc...
- oleganza 8y agoI'm using `.ok_or(SomeError)?` which converts Option into Result and opens Ok() for the rest of the scope, short-circuiting on Err(). I know about Swift's `guard` statement, but I never had a case yet when I didn't want to return Result in such kind of code, so ok_or was working for me well.
- steveklabnik 8y agoYou can use ? on an Option if your type returns an Option. If it returns a Result, you can use ok_or()?, and at some point in the nearish future, you can just use ?.
- vmarsy 8y agoI see, not very familiar with both those idioms `?` and `ok_or()?` My current understanding is that those would return an Error only? I was more describing cases where you do want to return, but not necessarily return an `Error`. For instance in a simplified example function that returns a boolean, you could decide to return `false`. is it possible there? // Function that returns a boolean value fn is_equal_to_ten(n: Option<u32>) -> bool { // some one liner that checks for None, if it's not none, gives you `x` when `n` matches content of `Some(x)` (not real code): if let Some(x) = n else { return false; /* what to do in case it's a None*/ } // `x` is available here: return (x == 10); } Would this be considered bad practice in Rust?
- steveklabnik 8y agoThe question mark operator works via a trait, Try. Both Option and Result implement Try. If you use ? on a None value, it will return None, just like using ? on an Err returns an Err. ok_or is a method on Option that would let you manually convert it to a Result. You could then combine it with ?, turning a None into a specific Err. It won’t help for stuff that returns bool, it’s true.
- vmarsy 8y agoThanks for the detailed answer :)
- Thiez 8y agoOften such functions can be rewritten to perform some operations "inside" the option. For example: fn is_equal_to_ten(n: Option<u32>) -> bool { n.map(|n|n == 10).unwrap_or_default() }
- hinkley 8y agoRelated to the discussion in the second link, it sounds like Mr Pearce got to coin the phrase 'flow typing' to describe this situation but this is something people have been talking about for a long time. Pseudocode: if (foo is a String) { foo.someStringMethod(); } Flip that around a little bit: if (foo is not a String) { return "error"; } foo.someStringMethod(); And you've got a guard clause that's fundamentally the same kind you're asking for. I've wanted this structure in a language for a very long time. I was happy to see it pop up in Kotlin and would love to see it in Rust as well.