GoLang 错误/接口机制

首先,我不太确定这个问题是与错误更相关,还是与 GoLang 中的接口更相关


我正在按照教程学习 GoLang。问题来自本教程页面


它是错误界面的基本演示。当我像这样更改代码时,我感到困惑:


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())

}

这段代码的输出是:


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

令我困惑的是 fmt 在什么条件下会隐式调用 MyError.Error() 接口。


据我了解,第一个和第二个 fmt.Println() 应该具有相同的变量类型:MyError。但显然第一个调用涉及到 MyError 类型的 Error() 的隐式调用,而第二个则没有。


是什么机制造成了这种差异?


感谢您调查这个初学者的问题!


qq_花开花谢_0
浏览 161回答 2
2回答

拉莫斯之舞

您的代码将 Error() 实现绑定到指针 *MyError。在您的代码中,您传递的是类型(准确地说是其副本)而不是指针。如果你改变err1 := MyError{time.Now(), "it works again"}到err1 := &MyError{time.Now(), "it works again"}它会按您的预期工作。

慕侠2389804

fmt.Println使用反射首先检查变量的类型,如果类型实现了Stringer接口,则调用该String方法。其次,如果该类型实现了Error它调用该Error方法的接口。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go