我试图了解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)
答案 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