Skip to content

1.golang defer语句

go语言中的defer语句会将其后面跟随的语句进行延迟处理。在defer归属的函数即将返回时,将延迟处理的语句按defer定义的逆序进行执行,也就是说,先按defer的语句最后执行,最后被defer的语句,最先被执行。

1.1 defer特性

1.关键字defer用于注册延迟调用

2.这些调用直到return前才被执行。因此,可以用来做资源清理

3.多个defer语句,按先进后出的方式执行

4.defer语句中的变量,在defer声明时就决定了

1.2 defer用途

1.关闭文件句柄

2.锁资源释放

3.数据库连接释放

案例

go
func main() {
	fmt.Println("start")
	defer fmt.Println("set1")
	defer fmt.Println("set2")
	defer fmt.Println("set3")
	fmt.Println("end")
}
func main() {
	fmt.Println("start")
	defer fmt.Println("set1")
	defer fmt.Println("set2")
	defer fmt.Println("set3")
	fmt.Println("end")
}

2. recover

异常捕获错误

运行时 panic 异常一旦被引发就会导致程序崩溃。这当然不是我们愿意看到的,因为谁也不能保证程序不会发生任何运行时错误。

不过,Go 语言为我们提供了专用于“拦截”运行时 panic 的内建函数--recover。他可以是当前的程序从运行时 panic 的状态中恢复并重新获得流程控制权。

注意:recover 只有在 defer 调用的函数中有效。

如果调用了内置函数 recover,并且定义该 defer 语句的函数发生了 panic 异常,recover 会使程序从 panic 中恢复,并返回 panic value。导致 panic 异常的函数不会继续运行,但能正常返回。在未发生 panic 时调用 recover,recover 会返回 nic。

go
package main

import "fmt"

func PrintSlice(s []string) {
	// recover 只能在defer中使用
	defer func() { // 匿名函数,()作用是立即执行
		if err := recover(); err != nil {
			// recover 捕获panic到错误后,程序不会崩溃,会执行defer中的代码
			fmt.Println("捕获到错误:", err)
		}
	}()
	fmt.Println(s)
	// 打印切片的第三个值
	fmt.Println(s[2])
}

func main() {
	s := []string{"1", "2"}
	PrintSlice(s)
}
package main

import "fmt"

func PrintSlice(s []string) {
	// recover 只能在defer中使用
	defer func() { // 匿名函数,()作用是立即执行
		if err := recover(); err != nil {
			// recover 捕获panic到错误后,程序不会崩溃,会执行defer中的代码
			fmt.Println("捕获到错误:", err)
		}
	}()
	fmt.Println(s)
	// 打印切片的第三个值
	fmt.Println(s[2])
}

func main() {
	s := []string{"1", "2"}
	PrintSlice(s)
}