Go 语言中捕获多个错误的方法
方法一:使用多个 if
语句和 recover
package main
import (
"fmt"
)
func get(index int) (ret int) {
defer func() {
if r := recover(); r!= nil {
fmt.Println("Some error happened!", r)
ret = -1
}
}()
arr := [3]int{2, 3, 4}
if index < 0 || index >= len(arr) {
panic("Index out of range")
}
// 模拟另一个可能导致 panic 的操作
if index == 1 {
panic("Invalid index value")
}
return arr[index]
}
func main() {
fmt.Println(get(1))
fmt.Println("finished")
}
在这个例子中,get
函数中包含多个可能导致 panic
的操作。使用 if
语句检查不同的条件,如果不满足条件就调用 panic
。每个 panic
会被 defer
中的 recover
函数捕获,并且可以根据不同的错误消息进行不同的处理。
方法二:使用自定义错误类型和多个 recover
块
package main
import (
"fmt"
)
type MyError struct {
Msg string
}
func (e MyError) Error() string {
return e.Msg
}
func get(index int) (ret int) {
defer func() {
if r := recover(); r!= nil {
switch err := r.(type) {
case MyError:
fmt.Println("Custom error:", err)
ret = -1
default:
fmt.Println("Other error:", err)
ret = -2
}
}
}()
arr := [3]int{2, 3, 4}
if index < 0 || index >= len(arr) {
panic(MyError{"Index out of range"})
}
// 模拟另一个可能导致 panic 的操作
if index == 1 {
panic(MyError{"Invalid index value"})
}
return arr[index]
}
func main() {
fmt.Println(get(1))
fmt.Println("finished")
}
在这个例子中:
-
定义了一个自定义错误类型
MyError
并实现了Error
方法,使其满足error
接口。 -
在
get
函数中,根据不同的错误条件使用panic
抛出不同的MyError
实例。 -
在
defer
中的recover
函数中,使用switch
语句根据错误类型进行不同的处理。
方法三:使用错误返回值而不是 panic
package main
import (
"fmt"
)
func get(index int) (int, error) {
arr := [3]int{2, 3, 4}
if index < 0 || index >= len(arr) {
return 0, fmt.Errorf("Index out of range")
}
// 模拟另一个可能导致错误的操作
if index == 1 {
return 0, fmt.Errorf("Invalid index value")
}
return arr[index], nil
}
func main() {
val, err := get(1)
if err!= nil {
fmt.Println("Error:", err)
} else {
fmt.Println(val)
}
fmt.Println("finished")
}
在这个例子中:
-
get
函数返回一个int
值和一个error
值。 -
当发生错误时,返回
0
和相应的错误信息,而不是使用panic
。 -
在
main
函数中,根据err
是否为nil
来判断是否发生了错误并进行相应处理。
解释:
-
使用多个
if
语句和recover
:-
这种方法比较简单直接,在函数中使用多个
if
语句检查不同的条件,当条件不满足时使用panic
触发错误。 -
defer
中的recover
函数会捕获panic
并处理,通过检查panic
的信息可以知道发生了什么错误。
-
-
使用自定义错误类型和多个
recover
块:-
自定义错误类型可以更好地表示不同类型的错误。
-
在
recover
时,可以使用类型断言和switch
语句对不同的错误类型进行不同的处理。
-
-
使用错误返回值而不是
panic
:-
这种方法更符合 Go 的错误处理原则,将错误作为函数的返回值,而不是中断程序执行。
-
调用者可以根据错误值决定如何处理错误,程序的流程更清晰,更易于理解和维护。
-
通常情况下,对于可预见的错误,推荐使用错误返回值而不是 panic
。只有在不可恢复的错误或程序中的严重错误时,才使用 panic
来终止程序。因为 panic