Ivan
Ivan

Reputation: 169

Why does returning a type that implements error interface call the Error() method automatically?

Link: https://play.golang.org/p/z50pUnAe4q

package main

import (
    "fmt"
    "time"
)

type MyError struct {
    When time.Time
    What string
}

func (e *MyError) Error() string {
    return fmt.Sprintf("at %v, %s",
        e.When, e.What)
}

func run() error {
    return &MyError{
        time.Now(),
        "it didn't work",
    }
}

func main() {
    if err := run(); err != nil {
        fmt.Println(err)
    }
}

I understand that the built in type error looks like this,

type error interface {
    Error() string
}

Meaning MyError implements error. The run() method returns a pointer to MyError type.

But the return type of run() method in the method signature is of type error.

How does the return statement in run() automatically call the Error() method?

Upvotes: 1

Views: 754

Answers (1)

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 250991

Here fmt.Println() is responsible for calling Error() method not run().

Quoting from docs:

The fmt package formats an error value by calling its Error() string method.

It is the error implementation's responsibility to summarize the context. The error returned by os.Open formats as "open /etc/passwd: permission denied," not just "permission denied." The error returned by our Sqrt is missing information about the invalid argument.

Hence, when you're trying to print err inside main() its Error() method is getting invoked.

Replace it with something else, then you won't see it in output: https://play.golang.org/p/IqScH02iGu

Upvotes: 3

Related Questions