对于怎么样来讲Go中的异常处理,其实我想了很久,最终还是决定用自己的想法,来把错误处理说一遍
错误的分类
在Go中,有两种错误,一种是让程序停止运行的错误(这种错误,如果被捕获到了,也可以不停止程序),另一种错误是不会让程序停止运行的
错误处理可以用到的函数和接口
func panic(v interface{})
func recover() interface{}
type error interface {
Error() string
}
panic()函数
调用这个函数,需要给这个函数传递一个空接口类型的值或者变量,调用完之后,程序会停止运行,不过完全停止运行之前,会把在 panic()函数调用之前调用的 defer函数内容执行完毕
在主函数中调用panic()函数
package main
import "fmt"
func main(){
fmt.Println("-----------------")
panic("程序终止?")
fmt.Println("程序好像被终止le")
}
输出
从这个输出可以看出,在panic()函数调用之前,fmt.Println()函数可以执行,但是在调用panic()函数后,后面的fmt.Println()函数并没有被执行。因为调用panic()函数后,程序就停止运行了
main.main()的这个输出是错误输出
在其它函数中执行panic()函数
package main
import "fmt"
func main(){
fmt.Println("-----------------")
test()
fmt.Println("程序好像被终止le")
}
func test(){
panic("程序终止?")
}
输出
这个输出跟在主函数调用panic()函数的输出是一样的,不过两者有些许的差别,就在后面错误输出打印的地方,它先打印出main.test(…),后再打印了main.main(),这个是因为在test()函数调用panic()函数之后,test()函数就因为错误停止执行了,停止后把这个错误传递给调用它的函数,在这里,也就是main()函数,因为main()函数没能处理这个错误,所以程序终止运行了
recover()函数
可以捕获程序中出现的错误,让程序不停止,可以继续执行
在什么地方recover()函数可以捕获到错误
在panic()函数执行之前,直接调用
package main
import "fmt"
func main(){
fmt.Println("-----------------")
recover()
panic("程序终止?")
fmt.Println("程序好像被终止le")
}
从输出看,是捕获不到的
在panic()函数调用之后,直接调用
package main
import "fmt"
func main(){
fmt.Println("-----------------")
panic("程序终止?")
recover()
fmt.Println("程序好像被终止le")
}
也是捕获不到错误,输出如上个例子
在panic()函数前,用defer + recover()函数
package main
import "fmt"
func main(){
fmt.Println("-----------------")
defer recover()
panic("程序终止?")
fmt.Println("程序好像被终止le")
}
也是捕获不到错误,输出如上个例子
在panic()函数前,用defer + 函数 + recover()
这里的函数,无论是普通函数还是匿名函数都可以
package main
import "fmt"
func main(){
fmt.Println("-----------------")
defer func() {
err := recover()
fmt.Println("recover捕获到错误了?", err)
}()
panic("程序终止?")
fmt.Println("程序好像被终止le")
}
从输出来看,错误确实是捕获到了,但是有个问题是,因为调用了panic()函数,程序还是停止了,没有继续执行
那有没有什么情况,panic()函数调用 + 被recover()捕获错误后,程序不会停止呢?当然是有了,就是panic()函数不是在主函数中被调用的情况,当在非主函数调用panic()函数后,把错误捕获,那么程序不会停止运行,而是会退出这个调用了panic()的函数而已,退出后,会继续执行被退出的函数外后面的内容
下面的例子,只是在主函数调用了,执行了panic()函数的函数,如果有多层的话,只会退出调用了panic()函数的函数
package main
import "fmt"
func main(){
fmt.Println("-----------------")
test()
fmt.Println("程序好像被终止le")
}
func test(){
defer func() {
err := recover()
fmt.Println("recover捕获到错误了?", err)
}()
panic("程序终止?")
fmt.Println("我是否还会被执行到")
}
error接口
创建error的两个函数
errors.New(text string) error
fmt.Errorf(format string, a ...interface{}) error
目前的话,我只知道这两个,但实际上,我只用过第一个函数
package main
import (
"errors"
"fmt"
)
func main() {
err := errors.New("创建一个error")
fmt.Println("err的值为:", err)
}
//输出:err的值为: 创建一个error
说真的,我这里只教怎么创建…
欢迎大家关注下个人的「公众号」:独醉贪欢