I'm seeing this trend in Rust that errors in Result
are returned like this:
fn do_something() -> Result<SomeType, Box<dyn std::error::Error>> {
// ...
}
Why are errors dynamic? Having come from a C++ background and prefering std::variant
over classical polymorphism (I'm relatively new to rust), I'm allergic to dynamic allocations, so I use them only when I really have to. I also find Rust's enums awesome to have included variants in them. Can someone please explain why isn't it standard/preferred/common to use errors as enum?
Errors are a fact of life in software, so Rust has a number of features for handling situations in which something goes wrong. In many cases, Rust requires you to acknowledge the possibility of an error and take some action before your code will compile.
Anyhow works with any error type that has an impl of std::error::Error , including ones defined in your crate. We do not bundle a derive(Error) macro but you can write the impls yourself or use a standalone macro like thiserror.
In application code, this is typically done for convenience. Making all error types statically known can be a maintenance nightmare: you have an ever-expanding enum of possible error types, most of which you are never going to try to handle individually. These error types have a way of contaminating type signatures far away from where the error would actually occur. Box<dyn std::error::Error>
keeps things very clean and the extra allocation isn't usually a problem because it only happens in the error case.
It's rarer in library crates, but some very generic code cannot possibly know what all of the possible error types can be. It can get very clumsy dealing with a type parameter for errors when composing a number of result types. A complex structure of possible statically-known error combinations can be conveniently collapsed into a single type, Box<dyn std::error::Error>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With