» Go语言快速入门 » 1. 基础篇 » 1.8 错误处理

错误处理

在 Go 中,错误处理被设计为显式的。它鼓励开发者明确地检查错误,而不是依赖异常。基本思想是可能遇到错误的函数需返回结果和错误两个值,该函数的调用方负责检查和处理返回的错误。

返回错误

可能遇到错误的函数将一个类型为 error 的值作为最后一个返回类型。

func divide(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("cannot divide by zero")
    }
    return a / b, nil
}

你可以使用 errors.New 创建一个新错误,或者使用 fmt.Errorf 创建更复杂的错误消息。

if err := someFunction(); err != nil {
    return fmt.Errorf("error in someFunction: %w", err)
}

处理错误

始终显式地检查错误。你可以使用 if 语句检查错误。

result, err := divide(10, 0)
if err != nil {
    fmt.Println("Error:", err)
} else {
    fmt.Println("Result:", result)
}

通过从函数返回错误将错误传播到调用堆栈上。每个层次可以决定如何处理或包装错误。

func compute() error {
    result, err := divide(10, 0)
    if err != nil {
        return fmt.Errorf("error in compute: %w", err)
    }
    // 继续处理
    // ...
}

Panic

panic 函数可用于引发运行时 panic。一般用于暴露无法有效处置的错误,甚至中断程序。

func example() {
    panic("serious error that cannot be handled here")
}

延迟

defer 语句可用于确保在程序执行的最后阶段执行函数调用,通常用于清理目的。这对于处理 panic 和释放资源很有用。

file, err := os.Open("example.txt")
if err != nil {
    return err
}
defer file.Close()
// ...

恢复

recover 函数用于重新获得对 panic 的控制。

func example() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered from panic:", r)
        }
    }()
    
    // 引发 panic 的代码
    panic("something went wrong")
}

自定义错误

可以通过实现 error 接口来创建自定义错误类型。

type MyError struct {
    Msg string
}

func (e *MyError) Error() string {
    return e.Msg
}

这允许你为错误提供更多的上下文和信息。

err := &MyError{Msg: "This is a custom error"}

总之,Go 代码偏向于显式错误处理,而不是抛异常。这可以使代码更可预测,也更可读。

代码挑战

编写一个名为 ReverseString 的函数,它以字符串作为输入,并返回其反转值。
记得处理输入字符串为空的情况,并为此情况返回自定义错误。

Loading...
> 此处输出代码运行结果
上页
下页