为什么返回实现了error接口的类型会自动调用Error()方法?

huangapple go评论87阅读模式
英文:

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

问题

链接:
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)
	}
}

我理解内置类型error的定义如下:

type error interface {
    Error() string
}

这意味着MyError实现了error接口。
run()方法返回了一个指向MyError类型的指针。

但是,run()方法在方法签名中的返回类型是error类型。

那么,run()方法中的返回语句是如何自动调用Error()方法的呢?

英文:

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?

答案1

得分: 3

在这里,fmt.Println() 负责调用 Error() 方法,而不是 run()

引用自文档

fmt 包通过调用错误值的 Error() 方法来格式化错误值的字符串。

错误实现的责任是总结上下文。os.Open 返回的错误格式为 "open /etc/passwd: permission denied",而不仅仅是 "permission denied"。我们的 Sqrt 返回的错误缺少关于无效参数的信息。

因此,当你尝试在 main() 中打印 err 时,它会调用其 Error() 方法。

将其替换为其他内容,然后你就不会在输出中看到它:https://play.golang.org/p/IqScH02iGu

英文:

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

huangapple
  • 本文由 发表于 2016年11月21日 16:34:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/40715792.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定