The new
go.dev website makes the language Spec hard to find, which is unfortunate.
The spec is here -- it is one of the easiest language specs to read.
The section on the built-in (pre-declared) error interface is here
Although struct values are allowed, they are very difficult to use correctly. I even
mess them up sometimes.
So until you get your feet with Go, I strongly recommend that you stick to only defining
methods on pointers to structs, and passing around pointers to structs. Otherwise
you will likely shoot yourself in the foot by trying to update a value that cannot be
updated, and will wonder why your updates were lost.
To create a struct that implements the error
interface, you need to define all the methods in the error interface. Fortunately, there
is only one.
type error interface {
Error() string
}
So your XError method could look look like this:
func (x *XError) Error() string {
return fmt.Sprintf("XError: i = %v", x.i)
}
Then have methods return &XError{i: 99} or whatever you need.
func getAnError() error {
return &XError{i: 99}