不按照我们期望执行的都可以称之为异常
fmt.Errorf("提示的内容")
errors.New("提示的内容")
注意点: 本质上两个方法底层的实现原理都是一样的package builtin中定义了一个接口
type error interface {
Error() string
}
package errors中定义了一个结构体
type errorString struct {
s string
}
errorString结构体实现了builtin中定义的接口
func (e *errorString) Error() string {
return e.s
}
所以errorString结构体实现了error接口
func New(text string) error {
return &errorString{text}
}
func TestThrowError(t *testing.T) {
if res, err := div(10, 0); err == nil {
fmt.Println(res)
} else {
fmt.Println(err)
}
}
func div(a int, b int) (res int, err error) {
if b == 0 {
// 创建异常的两种方式
err = fmt.Errorf("除数不能为0")
err = errors.New("除数不能为0")
} else {
res = a / b
}
return res, err
}
运行结果:
=== RUN TestThrowError
除数不能为0
--- PASS: TestThrowError (0.00s)
PASS
程序终止的方式:
func TestExceptionPanic(t *testing.T) {
/*
一种是程序发生异常时, 立刻退出终止程序继续运行
终止程序也分为两种:
1.系统自动终止
2.我们手动终止 (企业开发不常用)
格式: panic("提示信息")
*/
// 系统自动终止
//arr := [3]int{1, 3, 5}
//for i := 0; i < 20; i++ {
// fmt.Println(arr[i])
//}
res := div1(10, 0)
fmt.Println(res)
}
// 除法运算
func div1(a int, b int) (res int) {
if b == 0 {
//手动终止程序
panic("除数不能为0")
} else {
res = a / b
}
return res
}
func TestExceptionRecover(t *testing.T) {
/*
1.程序不要随意被终止, 只要不是程序不能运行了, 就尽量让改程序继续保持运行
2.在Go语言中如果panic异常, 那么可以通过defer和recover来实现panic异常的捕获, 让程序继续执行
注意点:
1.defer和recover必须在panic抛出异常之前定义
2.panic异常会随着函数的调用栈向外传递
例如: A函数调用了B函数, B函数调用了C函数
如果在C函数中抛出了一个panic异常, 那么这个异常会一层一层的传递到B和A
也就是在B和A函数中也能捕获到这个异常
*/
defer func() {
if err := recover(); err != nil {
fmt.Println("recover 捕获到了异常", err)
}
}()
res := div2(10, 0)
fmt.Println(res)
}
// 除法运算
func div2(a, b int) (res int) {
// 在当前函数中捕获
//defer func() {
// // defer无论所在的函数是正常结束,还是异常结束都会被执行
// // recover可以捕获panic异常
// if err := recover(); err != nil{
// fmt.Println("recover捕获到了", err)
// }
//}()
if b == 0 {
// 手动终止程序
panic("除数不能为0")
} else {
res = a / b
}
// 无效
//defer func() {
// // defer无论所在的函数是正常结束,还是异常结束都会被执行
// // recover可以捕获panic异常
// if err := recover(); err != nil{
// fmt.Println(err)
// }
//}()
return
}
运行结果:
=== RUN TestExceptionRecover
recover 捕获到了异常 除数不能为0
--- PASS: TestExceptionRecover (0.00s)
PASS
同一个函数中,多个 panic 异常,只要第一个会被捕获
func TestPanics(t *testing.T) {
/*
捕获异常注意点:
1.同一个函数中, 多个panic异常, 只有第一个会被捕获
*/
/*defer func() {
if err := recover(); err != nil {
fmt.Println(err) //异常1
}
}()
panic("异常1")
panic("异常2")
panic("异常3")
panic("异常4")*/
panicfuc()
}
func panicfuc() {
// 如果有异常写在defer中, 但是defer后面还有其它异常, 那么捕获到的是其它的异常
// 如果其它异常是写在defer前面, 那么和同一个函数中, 多个panic异常, 只有第一个会被捕获
defer func() {
if err := recover(); err != nil {
fmt.Println(err) // 异常B
}
}()
defer func() {
panic("异常B")
}()
panic("异常C")
}
运行结果
=== RUN TestPanics
异常B
--- PASS: TestPanics (0.00s)
PASS
微信号:程序员开发者社区
博客:CSDN 王小明
关注我们,了解更多
关注后:回复 AI, 有惊喜