error
下面是Go标准库对于error的定义
type error interface {
Error() string
}
可以看到Go中的error就是一个普通的接口,定义了一个Error()方法。
更多细节如下
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}
编程过程中,我们经常使用errors.New()
来返回一个error对象(内部errorString对象的指针)。
func New(text string) error {
return &errorString{
text}
}
- C返回值为int,代表成功或者失败。(由于redis底层由C实现,因此异常处理同上)
- C++引入exception,但是无法知晓被调用者(换个说法平时调用的第三方库中的函数)会抛出什么异常。
- Java引入checked exception,方法的所有者必须声明,调用者必须处理异常。启动时,可能抛出大量异常。
Go不同于以上的语言,未引入exception,而是实现了error interface的对象,交由调用者来判断定,相当于把exception扔给调用者处理。Go中有panic机制,panic意味着代码无法继续运行下去。(通常是重大错误导致程序已经无法正常继续下去,才会panic)如下。
func main() {
defer fmt.Println("can happen")
l := "Hello"
fmt.Println(l[6])
fmt.Println("can't happen")
}
上图可以看到打印出的错误原因以及堆栈信息,报错后程序直接退出,后续的代码不继续执行(derfer中的函数能正常执行)。
对于真正意外的情况, 那些表示不可恢复的程序错误, 例如索引越界、 不可恢复的环境问题、 栈溢出,我们才使用 panic 。对于其他的错误情况, 我们应该是期望使用 error 来进行判定。
想要程序触发panic后正常退出,可以使用recover()如下。
func main() {
defer func() {
if recover() != nil {
fmt.Println("normal exit")