Live data from Hacker News

Don't unwrap options: There are better ways (2024)

corrode.dev

1–10 of 63 posts

Re: Don't unwrap options: There are better ways (2024)

#2
let-else is awesome. definitely my favorite rust syntax. The compiler checks that the else branch will “diverge” (return, panic, break, or continue), so it’s impossible to mess it up.

the article says “It’s part of the standard library,” which gets the point across that it doesn’t require any external dependencies but it may be slightly misleading to those who interpret it literally - let-else a language feature, not part of the standard library, the relevant difference being that it still works in contexts that don’t have access to the standard library.

I tend to use Option::ok_or more often because it works well in long call chains. let-else is a statement, so you can’t easily insert it in the middle of my_value().do_stuff().my_field.etc(). However, Option::ok_or has the annoying issue of being slightly less efficient than let-else if you do a function call in the “or” (e.g. if you call format! to format the error message). I believe there’s a clippy lint for this, although I could be mixing it up with the lint for Option::expect (which iirc tells you to do unwrap_or_else in some cases)

I appreciate the author for writing a post explaining the “basics” of rust. I’ll include it in any training materials I give to new rust developers where I work. Too often, there’s a gap in introductory material because the vast majority of users of a programming language are not at an introductory level. e.g. in haskell, there might literally be more explanations of GADTs on the internet than there are of typeclasses

Re: Don't unwrap options: There are better ways (2024)

#4
Really useful article to learn about idiomatic Rust :)

In general I think there is a lack of intermediate Rust material that teaches you common design patterns, idiomatic Rust, and so on.

Even I (someone who's written hundreds of thousands of fairly complex Rust code) learnt about the let-else style solution from this article =).

Re: Don't unwrap options: There are better ways (2024)

#5
I have been using Zig a lot lately, and I just want to share the equivalent of the let-else solution in Zig:

   const user = getUser() orelse return error.NoUser;
If you only need user for a narrow scope like you would get from match, you can also use if to unwrap the optional.

    if (getUser()) |user| {
        // use user
    } else {
        return error.NoUser;
    }

Re: Don't unwrap options: There are better ways (2024)

#6
Talking about unwrapping: I’ve been using a rather aggressive list of clippy lints to prevent myself from getting panics, which are particularly deadly in real-time applications (like video games). unwrap/expect_used already got me 90% of the way out, but looking at the number of as conversions in my codebase, I think I have around 300+ numerical conversions (which can and do fail!)

    [lints.clippy]
    all = "deny"
    unwrap_used = "deny"
    expect_used = "deny"
    panic = "deny"
    indexing_slicing = "deny"
    unhandled_errors = "deny"
    unreachable = "deny"
    undocumented_unsafe_blocks = "deny"
    unwrap_in_result = "deny"
    ok_expect = "deny"

Re: Don't unwrap options: There are better ways (2024)

#7
> My main gripe with this error message is that it doesn’t explain why the ? operator doesn’t work with Option in that case… just that it doesn’t.

The error in question:

> the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`

It literally tells you why it doesn't work, wtf do you want?

Re: Don't unwrap options: There are better ways (2024)

#8

let-else is awesome. definitely my favorite rust syntax. The compiler checks that the else branch will “diverge” (return, panic, break, or continue), so it’s impossible to mess it up. the article says “It’s part of the standard library,” which gets the point across that it doesn’t require any external dependencies but it may be slightly misleading to those who interpret it literally - let-else a language feature, not…

> I believe there’s a clippy lint for this, although I could be mixing it up with the lint for Option::expect (which iirc tells you to do unwrap_or_else in some cases)

It's one lint rule which covers bunch of these _or_else functions: https://rust-lang.github.io/rust-clippy/master/#or_fun_call

Re: Don't unwrap options: There are better ways (2024)

#9

Talking about unwrapping: I’ve been using a rather aggressive list of clippy lints to prevent myself from getting panics, which are particularly deadly in real-time applications (like video games). unwrap/expect_used already got me 90% of the way out, but looking at the number of as conversions in my codebase, I think I have around 300+ numerical conversions (which can and do fail!) [lints.clippy] all = "deny" unwrap…

Does that mean your code is annotated with 300+ instances of `#[allow(clippy::unwrap_used)]` et al?

Re: Don't unwrap options: There are better ways (2024)

#10
post #5

I have been using Zig a lot lately, and I just want to share the equivalent of the let-else solution in Zig: const user = getUser() orelse return error.NoUser; If you only need user for a narrow scope like you would get from match, you can also use if to unwrap the optional. if (getUser()) |user| { // use user } else { return error.NoUser; }

And the same in Python:

  if user := get_user() is not None:
    # use user
  else:
    # return error
Although given the happy path code can mean you don't see the error condition for ages, I much prefer this:

  if (user := get_user()) is None:
    # return error

  # use user
Post reply on HN