Go基础:理解错误处理: Errors, Panic, Defer, Recover in Go

让我们进入 Go 中错误处理的课程!如果你来自使用异常来处理错误的语言,这种格式可能会看起来很特殊。

full lessons here👇:
https://programmerscareer.com/zh-cn/golang-basic-skill/

由AI生成,可能有错误,仅供参考

Topic: Error Handling

Go语言没有传统的try-catch-finally idiom,如Java和Python一样。Go鼓励程序员将错误视为函数返回结果的一种类型。

一个函数要么返回结果,要么返回错误,表示如下:

1
2
3
func openFile(fileName string) (file *File, err error) {
// ...
}

其中,err 是一个错误类型,是一个内置接口:

1
2
3
type error interface {
Error() string
}

任何定义了 Error() 方法的类型都满足 error 接口。在失败的情况下,函数返回 nil 对象和错误值。

要检查函数调用后的错误:

1
2
3
4
5
6
file, err := openFile("testfile")
if err != nil {
// 处理错误并返回
return
}
// 继续处理文件

Panic

Panic 是一个停止正常控制流的函数。当函数遇到 panic,它的执行将停止,任何延迟函数都将被执行,然后它将返回到调用者。

1
panic("a problem occurred")

这个方法会停止当前函数的执行,并开始解除 goroutine 的栈,运行任何延迟函数。

Defer

Defer 关键字允许我们推迟一个函数或方法或匿名方法的执行,直到当前函数的执行结束:

1
2
3
4
func worker() {
defer fmt.Println("The worker has stopped")
fmt.Println("The worker is working")
}

在这个例子中,将打印“The worker has stopped”消息,即使在代码中它之前。

Recover

Recover 是一个恢复 panicking goroutine 的函数。Recover 只有在延迟函数内部有效。在正常执行中,recover 调用将返回 nil 并没有其他影响。如果当前 goroutine 正在 panic,recover 调用将捕捉给定的 panic 值并恢复正常执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func except() {
if r := recover(); r != nil {
fmt.Println("Recovered", r)
}
}

func paycheck(amount int) {
defer except()
if amount > 0 {
fmt.Println(amount)
} else {
panic("Your paycheck is negative!")
}
}

func main() {
paycheck(1000)
fmt.Println("This message will still print.")
paycheck(-1000)
fmt.Println("This message will not.")
}

在这个例子中,recover 捕捉 panic 并允许程序继续执行。

Topics: Error Handling continuation — Panic and Recover

Panic 通常意味着 something went unexpectedly wrong。我们主要使用它来快速失败错误,这些错误在正常操作中 shouldn’t 发生或我们不能以优雅方式处理。

以下是一个示例:

1
2
3
4
5
6
7
8
package main
import "os"
func main() {
_, err := os.Create("/tmp/file")
if err != nil {
panic(err)
}
}

在上面的示例中,我们使用 panic 检查创建新文件时的 unexpected 错误。

Panic 的常见用法是 abort 如果函数返回一个我们不知道如何处理或不想处理的错误值。

现在,让我们谈论 recover。

recover 是一个恢复 panicking goroutine 的函数。recover 只有在延迟函数内部有效。在正常执行中,recover 调用将返回 nil 并没有其他影响。如果当前 goroutine 正在 panic,recover 调用将捕捉给定的 panic 值并恢复正常执行。

与 Python 和 Java 等语言不同,Go 语言中的错误只是值,可以被编程以从中恢复。

让我们看看一个示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main
import "fmt"
func myFunction() {
defer func() {
r := recover()
if r != nil {
fmt.Println("Recovered from", r)
}
}()
a, b := 10, 0
c := a / b
fmt.Println(c)
}

func main() {
myFunction()
fmt.Println("I am back in main.")
}

在上面的示例中,我们尝试将一个数字除以 0,这通常会导致 panic。但是,我们在函数内部恢复它,并执行下一行代码在 main 中。

English post: https://programmerscareer.com/go-basic-05/
作者:Wesley Wei – Twitter Wesley Wei – Medium
注意:本文为作者原创,转载请注明出处。

Go基础:了解 Timers, Tickers, Worker Pools, Waitgroups, Rate Limiting in Go Go基础:了解 Atomic, Mutex, Stateful Goroutines in Go

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×