?error接口类型
定义
- Go语言中返回的 error 类型究竟是什么呢?查看Go语言的源码就会发现 error 类型是一个非常简单的接口类型,如下所示:
- Go 语言的标准库代码包 errors 为用户提供如下方法:
所以errors包里提供两种方法(注意开头要有<font style="color:rgb(0,0,0);">import "errors"</font>
)
使用方法 | 场景 | |
---|---|---|
方式1 | err:= errors.New(...) 由于是interface接口类型,可以返回任意类型信息,string/int/…皆可 |
1. 创建一个 error 最简单的方法就是调用 errors.New 函数,它会根据传入的错误信息返回一个新的 error 2. 一般情况下,如果函数需要返回错误,就将 error 作为多个返回值中的最后一个(但这并非是强制要求)。 |
方式2 | 创建error接口类型的变量,调用方法, <font style="color:rgb(0,0,0);">errors.Error(...)</font> ; |
自定义错误 |
- fmt包里,其实也内置了方法
——方式3,语法fmt.Errorf("%...", ....)
方框内像是printf函数一样打印
应用
:::info 实际运用我们并我需要知道实际代码如何,我们先来看看基本用法
:::
- 方式1:
fmt.Errorf("%...", ....)
方框内像是printf函数一样打印
实例
结果: - 方式2:引入包
import "errors"
,error,New("%...", ...)
实例
结果:
:::info
实例2:err:= errors.New(...)
:::
b = 0,出错
结果:
b≠0,未出错
结果
:::info 实例3:除了上面的 errors.New 用法之外,我们还可以使用 error 接口自定义一个 Error() 方法,来返回自定义的错误信息。
:::
package main
import (
"fmt"
"math"
)
type dualError struct {
Num float64
problem string
}
func (e dualError) Error() string {
return fmt.Sprintf("Wrong!!!,because \"%f\" is a negative number", e.Num)
}
func Sqrt(f float64) (float64, error) {
if f < 0 {
return -1, dualError{Num: f} //????
}
return math.Sqrt(f), nil
}
func main() {
result, err := Sqrt(-13)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(result)
}
}
想法
- error不会去感知错误,要我们自己设置发生错误的场景,然后把
error.New()
/<font style="color:rgb(0,0,0);">errors.Error(...)</font>
作为返回值进行返回 errors.New(...)
和<font style="color:rgb(0,0,0);">errors.Error(...)</font>
一个是函数,一个是方法,但使用的时候,感觉和字符串无差别- 还有很多错误类型为了解,之后分析,这里综合了一下
panic
在通常情况下,向程序使用方报告错误状态的方式可以是返回一个额外的 error 类型值。 但是,当遇到不可恢复的错误状态的时候,如数组访问越界、空指针引用等,这些运行时错 误会引起 painc 异常。这时,上述错误处理方式显然就不适合了。反过来讲,在一般情况下, 我们不应通过调用 panic 函数来报告普通的错误,而应该只把它作为报告致命错误的一种方式。当某些不应该发生的场景发生时,我们就应该调用 panic。 一般而言,当 panic 异常发生时,程序会中断运行,并立即执行在该 goroutine(可以先理解成线程,在中被延迟的函数(defer 机制)。随后,程序崩溃并输出日志信息。日志信息包括 panic value 和函数调用的堆栈跟踪信息。不是所有的 panic 异常都来自运行时,直接调用内置的 panic 函数也会引发 panic 异常;panic函数接受任何值作为参数用于比较致命的错误,如数组访问越界、空指针引用等
语法:panic("...错误时返回的内容")
作用:显式调用panic函数,导致程序中断
实例1——自己主动调用:
实例2——程序出错编译器调用panic,如数组越界:
recover
定义
语法:recover()
一个函数
- 只在defer语句中有效
- 可感知panic,其范围: 1. 局部作用域 2. 延迟调用中引发的错误,可被后续延迟调用捕获,但仅最后⼀个错误可被捕获,见实例2
- 若发生panic,recover 会使程序从 panic 中恢复,并返回 panic value。导致 panic 异常的函数不会继续运行,但能正常返回。
- 在未发生 panic 时调用 recover,recover 会返回 nil。
应用
实例分析
一般会嵌入函数,defer func...
- 单独
recover()
- panic的时候,返回错误信息,此处是index out of range,也就是数组越界
- 不panic的时候,返回nil
- panic的时候,返回错误信息,此处是index out of range,也就是数组越界
嵌入if判断语句
上面不够完美,我们希望出错时候返回错误信息,不出错就正常运行,不返回,故习惯上嵌入if判断语句先对recover进行判断,err != nil
- 易错:感知范围是局部作用域,if 结构中并未出错,只会返回nil
- 正确:
- 易错:感知范围是局部作用域,if 结构中并未出错,只会返回nil
延迟调用中引发的错误,可被后续延迟调用捕获,但仅最后⼀个错误可被捕获(注意多个defer语句就算其中一个发生panic,程序不会中止,会忽略然后继续执行,顺序是先进后出,后进先出,堆栈顺序):
总结
recover()
是一个函数,会返回值,panic value/ nil,- 注意其范围
- 局部作用域
- 其它defer语句的错误,仅最后⼀个错误可被捕获
- 一般外面会套两层衣服,一件衣服是defer的函数,习惯是匿名函数,另一件是if 判断语句