have you ever actually done that? I have, its not easy. Please dont try to hand wave away negatives of the Rust type system.
Yes. I do it frequently. "#[derive(Error, Debug)]": https://github.com/dtolnay/thiserror#example
Much easier than implementing the error interface in go.
Rust is powerful enough to allow macros to remove annoying boiler-plate, and so most people using rust will grab one of the error-handling crates that are de-facto standard and remove the minor pain you're talking about.
In go, it's not really possible to do this because the language doesn't provide such macros (i.e. the old third-party github.com/pkg/errors wanted you to implement 'Cause', but couldn't provide sugar like 'this-error' does for it because go is simply less powerful).
I've found implementing errors in go to be much more error-prone and painful than in rust, and that's not to mention every function returning untyped errors, meaning I have no clue what callers should check for and handle new errors I add.
is this a joke? You have to import a third party package, just to implement an error interface? Here is Go example, no imports:
type errorString string
func (e errorString) Error() string {
return string(e)
}Let's look at a common example: you want to return two different types of errors and have the caller distinguish between them. Let me show it to you in rust and go.
Rust:
#[derive(Error, Debug)]
pub enum MyErrors {
#[error("NotFound: {0}")
NotFound(String),
#[error("Internal error")]
Internal(#[source] anyhow::Error),
}
The equivalent go would be something like: type NotFoundErr struct {
msg string
}
func (err NotFoundErr) Error() string {
return "NotFound: " + err.msg
}
func (err NotFoundErr) Is(target error) bool {
if target == nil {
return false
}
// All NotFoundErrs are considered the same, regardless of msg
_, ok := target.(NotFoundErr)
return ok
}
type InternalErr struct {
wrapped error
}
func (err InternalErr) Error() string {
return fmt.Sprintf("Internal error: %s", err.wrapped)
}
func (err InternalErr) Unwrap() error {
return err.wrapped
}