Hacker News new | ask | show | jobs
by mrheosuper 263 days ago
I have no specific compaints, but here one example i saw online, and i'm talking from a C dev perspective.

  let x: Option<Result<Vec<i32>, std::num::ParseIntError>> = Some(Ok(vec![1, 2, 3]));
  let flattened = x
 .map(|r| r.unwrap_or_default())
 .unwrap_or_else(|| Vec::<i32>::new());
I have no idea what the code is doing here, but while reading python or JS code, i can make an educated guess what it's doing.

I have no experience with Rust so it makes sense i dont understand, but i also have no experience with Python or JS.

2 comments

It is of course impossible to know the context in which you saw this, but I will say this is a particular idiomatic way to write Rust which won't mesh with your C knowledge.

Also this code isn't a thing you'd actually do, it's maybe an illustration or part of an example I suppose

You see that vec![1, 2, 3] ? That's what we're getting at the end, a growable array with three integers in it. All the other stuff is machinery to handle errors which in fact have not happened.

    let flattened = vec![1, 2, 3];
Is the same effect, although probably for style you'd write:

    let flattened: Vec<i32> = vec![1, 2, 3];
It's a bit unusual for a type to be wrapped in both an option and a result, since they have a lot of overlap. They're both union types, but semantically, Result takes the place of throwing an exception (Ok is your return value or here's the error) while Option takes the place of a pointer (Some is an instance of the underlying type, vs None which the null case).

Normally these union types would be handled with a match, or an if let, eg:

    if let Some(x) = fn_returning_an_option() {
        do_thing_with_x(x);
    } else {
        // handle that it was none
    }
The unwrap functions are basically just shortcuts for this, with the most extreme being unwrap() itself, which simply returns the Ok/Some value if present, and otherwise triggers a panic state resulting in the program exiting.

But all of this is rust forcing the developer to either address the null case, or explicitly put in an "unwrap" to acknowledge that they're not addressing it. This is in contrast to C or C++ where you just myPtr->lol wherever you want, and if myPtr is null then it's a segfault.

So that's the worst of it. The rest is the function chain, which is a bit obscured by lack of indentation, and that the functions are being passed lambdas.