Yeah, I see. But one difference still would be that each time we need to return a specific custom io::Error
, we have to call the corresponding "factory" function, which in turn has to call io::Error::new()
in order to create a new instance of the io::Error
. Since the "factory" function takes no parameters and the resulting io::Error
instance will always be totally equivalent (for a concrete "factory" function), creating a new instance each time seems like an avoidable overhead.
If we actually were able to instantiate our custom io::Error
exactly once and have it stored as a const
value, then we could simply return the const
value "as-is" whenever we need to.
Admittedly, the const
Error still would have to be Copy
'd when we return it "by-value". But, nonetheless, that should be less overhead and "cleaner" than constructing an entirely new one...
In functional programming it is very common to have different "plain old data" structs which act as containers for different data. For example, say you are processing data in a way where only certain things will be valid at different times in the operation, then you might create a different struct for each stage which holds only the data that is valid for that stage.
Having a separate "container" struct
for each stage, which wraps any value that is valid at the specific stage (and never contains "invalid" values for the stage), seems reasonable to me. But not having a separate struct
for each valid value, and that multiplied by the number of stages.
Similarly, I wouldn't want to have a separate struct
for each error, only for each "class" of errors.
If it were me, instead of using one common error enum with different variants, I'd probably create separate error types for each case and add an impl From<TimedOut>
for std::io::Error
so ?
can automatically convert my TimedOut
error to a std::io::Error
. That way you can reuse your TimedOut
and Cancelled
errors elsewhere or maybe only return Result<_, Cancelled>
rather than a more generic Result<_, MyError>
, and you get a more precise error chain.
Thing is, I want to implement Read
and Write
which require the result to be a io::Result
(i.e. Result<T, io::Error>
) and therefore I have to wrap "my" error in an io::Error
.