这两个err值有什么区别?

时间:2019-07-15 07:41:40

标签: string go methods go-interface

我试图了解golang界面,我的问题是为什么要err2。未定义的内容。

这是一个简单的代码。输出表明err和err2与* main.MyError具有相同的类型,但是err2没有字段“ What”,因此err和err2之间必须有一些区别,但是我无法在此处找到区别。我刚刚开始学习golang,不久以后,任何帮助将不胜感激。

package main

import (
        "fmt"
        "time"
        "reflect"
)

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() {
        err := &MyError{time.Now(), "Hello"}
        fmt.Println(reflect.TypeOf(err))
        fmt.Println(err.What)   

        err2 := run()
        fmt.Println(reflect.TypeOf(err2))
        fmt.Println(err2.What)
}

预期输出:

main.MyError
Hello
main.MyError
it didn't work

实际输出:

\# command-line-arguments ./test.go:34:18: err2.What undefined (type error has no field or method What)

2 个答案:

答案 0 :(得分:1)

函数run()返回类型error的值,它是接口类型。是的,它包装了具体类型*MyError的值,但是要访问MyError的字段,您需要使用type assertion

fmt.Println(err2.(*MyError).What)

Go Playground上尝试。

请注意,error类型的值可能包含其他具体类型的值,实际上是任何实现error接口的值。如果它包含另一个类型的值,则上面的类型声明将导致运行时出现紧急情况。

如果不确定err2实际上是否拥有类型*MyError的值,并且要避免运行时出现恐慌,则可以使用类型断言的特殊形式来获取此信息,并且仅在以下情况下执行操作:是这样的:

if myerror, ok := err2.(*MyError); ok {
    fmt.Println(myerror.What) // Here myerror has static type *MyError
} else {
    fmt.Println("Some other error:", err2)
}

Go Playground上尝试这个。

答案 1 :(得分:0)

我认为错误类型的接口使您可以使用Error()方法,而在具体结构中没有任何细节。您可以检查Go Playground