jakub_neruda, Czech

Tip 40 of #TuesdayCodingTips - Rust's error propagation is amazing

As much as I love C++, its optional and expected objects can just envy one killer feature of their Rust counterparts. If you're working with a Result<T, E> in a function that returns a Result<U, E2>, you can use operator ? to simply unwrap the Ok value into a variable. If the result contains an error, Rust will not panic; rather, it returns that error from the current function similar to how exception would bubble up the code. The only limitation is that the function must return Result with the error type to which the propagated error can be implicitly converted.

Option also supports the operator ?, which either propagates None up the call stack or safely unwraps the stored Some.

I'd kill to have this in C++, where you would have to employ non-standard compiler extensions to create a macro that would be at least close.

#rust #programming #tips

smoku,
@smoku@vivaldi.net avatar

@jakub_neruda ups it up a notch. You don't need to specify the error type, as the compiler will figure out the union of all possible bubbling-up errors and infer it into the function return type signature.

jakub_neruda,

@smoku I am not sure I like this. One of the reasons why people dislike exceptions is that you never know the full set of exceptions that can be thrown from the function.

If Zig does this in compile-time then do you have visibility into the full set of exceptions?

lhp,
@lhp@mastodon.social avatar

@jakub_neruda @smoku You can still annotate function definitions with their full error-set (which most things in the std lib do). And f.e. switching on a functions error, even if not annotated, is still treated as exhaustive.

jakub_neruda,

@lhp @smoku Not sure what you mean by this. Can you please explain more?

lhp,
@lhp@mastodon.social avatar

@jakub_neruda @smoku The annotation thing or the exhaustive thing?

If it's the latter:

function() catch |err| {
switch (err) {
// ...
}
};

The compiler forces you to handle all possible error cases in the switch (or use else) even for non-annotated functions. It will also complain if you put an error case in there the function can't return (unless explicitly annotated with anyerror, which skips error-set inference).

Does that clear things up?

lhp,
@lhp@mastodon.social avatar

@jakub_neruda @smoku If it's about annotating functions:

No annotation:

fn foo (i: u8) !void {}

Annotation:

fn foo (i: u8) error{DeviceLiterallyOnFire}!void {}

Disable inference:

fn foo (i: u8) anyerror!void {}

Function that can't return an error:

fn foo (i: u8) void {}

lhp,
@lhp@mastodon.social avatar

@jakub_neruda @smoku As you might expect, if you annotate a function with an error set, the compiler will also complain if you try to return an error not in that set.

  • All
  • Subscribed
  • Moderated
  • Favorites
  • rust
  • DreamBathrooms
  • ngwrru68w68
  • InstantRegret
  • magazineikmin
  • thenastyranch
  • rosin
  • khanakhh
  • tacticalgear
  • Youngstown
  • slotface
  • Durango
  • kavyap
  • mdbf
  • ethstaker
  • JUstTest
  • GTA5RPClips
  • modclub
  • tester
  • provamag3
  • osvaldo12
  • cisconetworking
  • everett
  • cubers
  • normalnudes
  • megavids
  • Leos
  • anitta
  • lostlight
  • All magazines