常规错误处理方式
- 直接检查:在调用函数后,直接检查返回的错误值是否为
nil
。
package main
import (
"fmt"
)
type Divider interface {
Divide(a, b int) (int, error)
}
type MyDivider struct{}
func (md MyDivider) Divide(a, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}
func main() {
var d Divider = MyDivider{}
result, err := d.Divide(10, 2)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Result:", result)
}
- 使用
errors.Is
检查特定错误:如果有预定义的错误类型,可以使用 errors.Is
来检查返回的错误是否为特定类型。
package main
import (
"errors"
"fmt"
)
var ErrDivisionByZero = errors.New("division by zero")
type Divider interface {
Divide(a, b int) (int, error)
}
type MyDivider struct{}
func (md MyDivider) Divide(a, b int) (int, error) {
if b == 0 {
return 0, ErrDivisionByZero
}
return a / b, nil
}
func main() {
var d Divider = MyDivider{}
result, err := d.Divide(10, 0)
if err != nil {
if errors.Is(err, ErrDivisionByZero) {
fmt.Println("Caught division by zero error")
} else {
fmt.Println("Other error:", err)
}
return
}
fmt.Println("Result:", result)
}
- 使用
errors.As
进行类型断言:当错误是一个自定义类型时,可以使用 errors.As
来获取具体的错误类型。
package main
import (
"errors"
"fmt"
)
type CustomError struct {
Msg string
}
func (ce CustomError) Error() string {
return ce.Msg
}
type Divider interface {
Divide(a, b int) (int, error)
}
type MyDivider struct{}
func (md MyDivider) Divide(a, b int) (int, error) {
if b == 0 {
return 0, CustomError{"division by zero"}
}
return a / b, nil
}
func main() {
var d Divider = MyDivider{}
result, err := d.Divide(10, 0)
if err != nil {
var customErr CustomError
if errors.As(err, &customErr) {
fmt.Println("Custom error:", customErr.Msg)
} else {
fmt.Println("Other error:", err)
}
return
}
fmt.Println("Result:", result)
}
设计包含错误返回的接口方法
- 简单示例:上面的
Divide
方法就是一个包含错误返回的接口方法示例。接口定义如下:
type Divider interface {
Divide(a, b int) (int, error)
}
- 原则:
- 清晰定义错误场景:在文档或代码注释中明确说明在什么情况下会返回错误。例如在
Divide
方法中,通过注释说明当 b == 0
时会返回 “division by zero” 错误。
- 错误类型一致性:如果可能,尽量返回一致的错误类型或基于某个基础错误类型构建。如在
errors.Is
的示例中,定义了 ErrDivisionByZero
错误,所有的除法为零错误都返回这个预定义错误,方便调用者统一处理。