-1

I am creating a custom error and used it as a function return:

type MyError struct {
    Name string
}

func (me *MyError) Error() string {

    return me.Name + " is my error"
}

Function that returns the custom error:

func (anyStruct *AnyStruct) Validate() error {
    // if Any verification {

        return &MyError{Name: "MyError"}

    //}
}

Why can't I return as a value instead of a reference? If I try to return as a value:

return MyError{Name: "MyError"}

The editor's linter complains about an error:

cannot use (MyError literal) (value of type MyError) as error value in return statement: missing method Error

Also, I am confused by the fact that a reference is being returned but the function signature does not inform that a pointer will be returned:

func (anyStruct *AnyStruct) Validate() error { instead of func (anyStruct *AnyStruct) Validate() *error {

Matheus Saraiva
  • 1,144
  • 1
  • 11
  • 33
  • 3
    For why the linter wants you to use a pointer, check out the most voted answer to [this question](https://stackoverflow.com/questions/50333428/custom-errors-in-golang-and-pointer-receivers). For why the return type is `error` and not `*error`, that is because `error` is an `interface` (which you can find in the `builtin` package if you'd like to see it). – phonaputer Sep 09 '20 at 23:27
  • @phonaputer _"""For why the return type is error and not *error, that is because error is an interface (which you can find in the builtin package if you'd like to see it)"""_ Does it mean that whenever a function's return type is an interface I don't need the pointer flag ("*"), even if the return is a reference? – Matheus Saraiva Sep 10 '20 at 00:21
  • 2
    Yes, that is correct. You might want to read up on how interfaces work in Go. – phonaputer Sep 10 '20 at 00:45

1 Answers1

2

error is an interface type so a type that can be used as an error must implement the Error() method. The type in your code that implements Error() is *MyError (ie pointer to MyError). When Validate() returns the return value is implicitly converted to an error - only *MyError (and not MyError) can be converted to an error.

To do what you want you should instead have MyError implement Error().

func (me MyError) Error() string {
    return me.Name + " is my error"
}

Note that whatever type you return if the function returns an error the return value will be stored in an interface (remember error is an interface type). And like most types a pointer can be stored in an interface. Also be careful using the word "reference" type - in Go that usually refers to types (interface, map, etc) that internally contain pointers though I guess it would also includes pointers.

Andrew W. Phillips
  • 3,254
  • 1
  • 21
  • 24