4 ms·
One of the more interesting semi-recent additions to stable rust is the question mark operator. It's not covered in this Rust Error Handling article, but it's
by wyldfire 8y ago
One of the more interesting semi-recent additions to stable rust is the question mark operator. It's not covered in this Rust Error Handling article, but it's got some of the early-exit appeal of exceptions without too much unwind magic.
Unfortunately I haven't been able to get the question mark operator to work yet with my code, but it looks appealing. It's not 100% obvious to me what qualities my Result type needs in order to be able to make it work. Or whether it's bound in practice to the Result type(s) defined in std. I'm sure those details are all in the docs somewhere but I spent the time to look yet.
- CUViper 8y agoOne thing you may be missing is that the `Result::Err` in your return type must implement `From` for the `Result::Err` type where you're using the `?` operator. That's already covered if those `Err` types are identical (`From<T> for T`), otherwise you need to implement the conversion. impl From<QuestionError> for ReturnError { fn from(error: QuestionError) -> ReturnError { // TODO unimplemented!() } }
- wyldfire 8y agoOh yeah, that's likely it. Thanks! It it safe to just put a noop in there? What's From-ness? Is QuestionError defined in std? Where do I read more? EDIT: oh I see, I didn't read carefully. I just need to provide a conversion. Your example is very clear.
- ds206 8y agoIt's how you explicitly cast from one type to another. To use the ? operator with a custom error type, it needs to be converted to the std error type.
- steveklabnik 8y agoIt needs to be converted to whatever error type the function returns. That can be anything.
- Falell 8y agoThe ? operator is tied to std::ops::Try, and std::convert::From. https://doc.rust-lang.org/std/ops/trait.Try.html https://doc.rust-lang.org/std/ops/trait.Try.html https://doc.rust-lang.org/std/convert/trait.From.html https://doc.rust-lang.org/std/convert/trait.From.html
- wyldfire 8y agoOh, hey, this was great (the link to the 'From' trait). "enum CliError" -- this example was crystal clear and answered a lot of my questions.
- ChrisSD 8y agoIt's worth reading through the doc page. It's not not too long: https://doc.rust-lang.org/stable/book/ch09-02-recoverable-errors-with-result.html https://doc.rust-lang.org/stable/book/ch09-02-recoverable-er...
- wyldfire 8y agoI had read that doc page but IMO it's not very clear about how you should use Result types. It's great for showing how you might want to use the question mark with libstd but IMO less clear about writing your own functions and Result<> types (though apparently the most interesting constraint seems to be regarding your Result's E type). Someone elsewhere in this thread linked to an example of `impl From<io::Error>` and IMO that's a clear, explicit example of how to do it.
- rabito 8y agoAlso, if you use Box<Error> or failure[1]'s Error type you can get around implementing most of the conversion Traits, but you lose the ability to tell which errors can happen by just looking at the type signature and doing exhaustive matching on them. [1]: https://github.com/withoutboats/failure https://github.com/withoutboats/failure
- csomar 8y agoIf you can post your code, we can help you out. One requirement, is that your function returns a Result<Ok, Err>. The Err needs to implement the same type for all the type returned. This means you can use the "?" operator for functions that you did not create (libraries) but you'll also have to convert their Error type to your Error type.