Vincent Wang
Vincent Wang

Reputation: 13

GoLang Error/Interface Mechanism

Firstly, I am not quite sure if this problem is more relevant to error, or to interface in GoLang

I am catching up the GoLang by following the tutorial. The question came with this tutorial page

It is a basic demonstration of the error interface. When I change the code a bit like this, I got confused:

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() *MyError {
    return &MyError{
        time.Now(), "it didn't work",
    }
}

func main() {
    if err := run(); err != nil {
        fmt.Println(err)
    }
    err1 := MyError{time.Now(), "it works again"}
    fmt.Println(err1)
    fmt.Println(err1.Error())
}

The output of this piece of code is:

at 2015-04-06 15:00:07.1541719 +0800 CST, it didn't work
{2015-04-06 15:00:07.155172 +0800 CST it works again}
at 2015-04-06 15:00:07.155172 +0800 CST, it works again

The thing confused me is under what condition the fmt will implicitly call MyError.Error() interface.

To my understanding, the first and second fmt.Println() should have the same variable type: MyError. But obviously the first call involved an implicit call of Error() of the MyError type, while the second did not.

What mechanism made this difference?

Thanks for looking into this beginner's question!

Upvotes: 1

Views: 3382

Answers (2)

IamNaN
IamNaN

Reputation: 6864

Your code binds the Error() implementation to a pointer *MyError.

In your code you are passing the type (a copy thereof to be precise) rather than a pointer.

If you change

err1 := MyError{time.Now(), "it works again"}

to

err1 := &MyError{time.Now(), "it works again"}

it will work as you expect.

Upvotes: 1

user4753631
user4753631

Reputation: 1

fmt.Println uses reflection to firstly check the type of the variable and if the type implements the Stringer interface then it calls the String method. Secondly if the type implements the Error interface it calls the Error method.

Upvotes: 0

Related Questions