Understanding std vs. async_std vs. tokio

This repo I created has really helped me understand some differences between the options in the subject.
https://github.com/mvolkmann/rust-parallel-options

I'd love to get feedback on anything I've done here, particularly if anything is not idiomatic or could be simplified.

I do have one specific question in a comment here:
https://github.com/mvolkmann/rust-parallel-options/blob/0f2ef70f48bb871aeff7c82cd381f19f679a54cd/src/tokio_demo.rs#L79

The double question mark is because Tokio more closely mirrors the API of the standard library for this API, which says that joining a JoinHandle should return a Result<T, JoinError> where T is the return value of the spawned task.

Since the task returns Result<f64, io::Error>, this results in the return value of

Result<Result<f64, io::Error>, JoinError>

and to unwrap a twice-nested Result requires two question marks.

In async-std, they have an unwrap inside the .await that removes the need for you to have the outer Result.

Note that a JoinError happens mainly if the spawned task panics.


Note that comparing to this:

https://github.com/mvolkmann/rust-parallel-options/blob/0f2ef70f48bb871aeff7c82cd381f19f679a54cd/src/async_std_demo.rs#L73-L75

The .unwrap() then question mark handles the same problem where the standard library gives you a double-nested result, except you handle the inner one by unwrapping rather than with a question mark.

Again, with async-std, you would still panic in the same case, the unwrap is just somewhere inside the impl of .await on a JoinHandle, so you don't have to do it.

3 Likes

Would you use a different approach for these lines?

let sum1 = handle1.join().unwrap()?;
let sum2 = handle2.join().unwrap()?;

I see that I can't just replace .unwrap() with ?.

Nah, it's fine. That unwrap will only panic if there is a panic inside the spawned task.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.