Go学习笔记—错误处理
Go语言使用一个独立的,明确的返回值来传递错误信息。
Go语言的错误处理方式能清楚的知道哪个函数返回了错误,并能像调用那些没有出错的函数一样调用。
内置接口
Go语言中的错误通常是最后一个返回值并且是error
类型。error
是一个内置的接口。
Go语言中可以使用errors.New
构造一个使用给定的错误信息的基本error
值。
func f1(arg int) (int,error){
if arg == 42{
return -1,errors.New("can't work with 42") //构造一个指定错误信息的基本error值
}
return arg + 3,nil
}
func main(){
for _,i := range []int{
7,42}{
if r,e := f1(i);e != nil{
fmt.Println("f1 failed:",e)
}else{
fmt.Println("f1 worked:",r)
}
}
}
//f1 worked: 10
//f1 failed: can't work with 42
在返回的错误信息中,如果返回nil
,则代表没有错误。
自定义错误类型
Go语言中可以通过error()
方法,来自定义错误类型。
通过与结构体结合,定义符合结构体的方法,来返回错误内容。
type argError struct{
arg int
prob string
}
func (e *argError) Error() string{
return fmt.Sprintf("%d-%s",e.arg,e.prob)
//函数的返回值是字符串,所以使用Sprintf函数
}
func main(){
for _,i := range []int{
7,42}{
if r,e := f2(i);e != nil{
fmt.Println("f2 failed:",e)
}else{
fmt.Println("f2 worked:",r)
}
}
}
//f2 failed: 10
//f2 worked: 42-can't work with it
-
fmt.Sprintf() //Sprintf formats according to a format specifier and returns the resulting string. //根据格式说明,返回结果字符串
通过定义方法,来返回自定义错误类型。
func f2(arg int) (int,error){
if arg == 42{
return -1,&argError{
arg,"can't work with it"}
}
return arg + 3,nil
}
func main(){
_,e := f2(42)
if ae,ok := e.(*argError);ok{
//类型断言,ok为true才执行语句
fmt.Println(ae.arg)
fmt.Println(ae.prob)
}
}
//42
//can't work with it
这其中使用到类型断言,可以获取自定义错误类型中的数据。
-
//类型断言的格式: x.(T) //x 为自定义类型的实例 //T 为断言可能存在的类型
-
类型断言返回两个参数,第一个参数是
x
转化为T
类型后的变量,第二个值是一个布尔值,若为true
则表示断言成功,为false
则表示断言失败。
panic和recover
panic
和recover
是Go语言的内置函数,用来进行错误处理。
panic
意味着有些出乎意料的错误发生。通常我们用它来表示在程序正常运行中出现的不应该出现的,或者没有处理好的错误。
panic
可以在任何地方引发,recover
只有在defer
调用的函数中才有效。
func f3(){
defer func(){
err := recover()
if err != nil{
fmt.Println("用来测试recover错误处理")
}
}()
panic("用来测试panic错误处理")
}
func main(){
for _,i := range []int{
7,42}{
if r,e := f1(i);e != nil{
fmt.Println("f1 failed:",e)
}else{
fmt.Println("f1 worked:",r)
}
}
f3()
for _,i := range []int{
7,42}{
if r,e := f2(i);e != nil{
fmt.Println("f2 failed:",e)
}else{
fmt.Println("f2 failed:",r)
}
}
}
//f1 worked: 10
//f1 failed: can't work with 42
//panic: 用来测试panic错误处理
//goroutine 1 [running]:
//main.f3(...)
// E:/GoProjects/StudyGO/0809.go:32
//main.main()
// E:/GoProjects/StudyGO/0809.go:44 +0x1eb
运行结果显示,程序在运行完f3()
后,出现错误。这是因为f3()
中的panic
导致程序崩溃。
func f3(){
defer func(){
err := recover()
if err != nil{
fmt.Println("用来测试recover错误处理")
}
}()
panic("用来测试panic错误处理")
}
//在使用panic的函数中,添加defer和recover语句后,函数即可正常运行
//f1 worked: 10
//f1 failed: can't work with 42
//用来测试recover错误处理
//f2 failed: 10
//f2 failed: 42-can't work with it