Golang异常处理机制 panic recover defer详解

简单的例子
package main
 
import "fmt"
 
func main() {
	var array [5]int
 
	// 延迟调用匿名函数 (匿名函数在主函数结束之前最后调用,可以捕获主函数中的异常)
	defer func() {
		err := recover()  // recover() 捕获panic异常,获得程序执行权。
		fmt.Println("recover()后的内容!!")  // recover()后的内容会正常打印
		if err != nil {
			fmt.Println(err)  // runtime error: index out of range
		}
	}()
 
	index := 10
	array[index] = 10   // 会抛出panic异常 (数组下标越界)
 
	fmt.Println("异常发生后的内容!!")  // 异常之后的内容不会打印
}

运行结果如下:

:go run main.go
recover()后的内容!!
runtime error: index out of range [10] with length 5
嵌套的例子
package main

import "fmt"

func main() {
	var array [5]int

	defer func() {
		err := recover()
		fmt.Println("recover()后recover()后的内容!!")
		if err != nil {
			fmt.Println(err)
		}
	}()

	// 延迟调用匿名函数 (匿名函数在主函数结束之前最后调用,可以捕获主函数中的异常)
	defer func() {
		err := recover()               // recover() 捕获panic异常,获得程序执行权。
		fmt.Println("recover()后的内容!!") // recover()后的内容会正常打印
		if err != nil {
			fmt.Println(err) // runtime error: index out of range
		}
		panic("recover()后panic()!!")
	}()

	index := 10
	array[index] = 10 // 会抛出panic异常 (数组下标越界)

	fmt.Println("异常发生后的内容!!") // 异常之后的内容不会打印
}

运行结果如下:

:go run main.go
recover()后的内容!!
runtime error: index out of range [10] with length 5
recover()recover()后的内容!!
recover()panic()!!
继续嵌套
package main

import "fmt"

func main() {
	var array [5]int

	defer func() {
		err := recover()
		fmt.Println("recover()后recover()后的内容!!")
		if err != nil {
			fmt.Println(err)
		}
	}()

	// 延迟调用匿名函数 (匿名函数在主函数结束之前最后调用,可以捕获主函数中的异常)
	defer func() {
		panic("recover()前panic()!!")
		err := recover()               // recover() 捕获panic异常,获得程序执行权。
		fmt.Println("recover()后的内容!!") // recover()后的内容会正常打印
		if err != nil {
			fmt.Println(err) // runtime error: index out of range
		}
	}()

	index := 10
	array[index] = 10 // 会抛出panic异常 (数组下标越界)

	fmt.Println("异常发生后的内容!!") // 异常之后的内容不会打印
}

运行结果如下:

:go run main.go
recover()后recover()后的内容!!
recover()前panic()!!

注意只要panic()当前函数就不会执行了。

嵌套
package main

import "fmt"

func main() {
	var array [5]int

	defer func() {
		err := recover()
		fmt.Println("1")
		if err != nil {
			fmt.Println(err)
		}
		err = recover()
		fmt.Println("2")
		if err != nil {
			fmt.Println(err)
		}
	}()

	// 延迟调用匿名函数 (匿名函数在主函数结束之前最后调用,可以捕获主函数中的异常)
	defer func() {
		panic("3")
		err := recover() // recover() 捕获panic异常,获得程序执行权。
		fmt.Println("4") // recover()后的内容会正常打印
		if err != nil {
			fmt.Println(err) // runtime error: index out of range
		}
	}()

	index := 10
	array[index] = 10 // 会抛出panic异常 (数组下标越界)

	fmt.Println("5") // 异常之后的内容不会打印
}

运行结果如下:

:go run main.go
1
3
2
继续嵌套

加一条多余的recover():

package main

import "fmt"

func main() {
	var array [5]int

	defer func() {
		err := recover()
		fmt.Println("1")
		if err != nil {
			fmt.Println(err)
		}
		err = recover()
		fmt.Println("2")
		if err != nil {
			fmt.Println(err)
		}
		err = recover()
		fmt.Println("6")
		if err != nil {
			fmt.Println(err)
		}
	}()

	// 延迟调用匿名函数 (匿名函数在主函数结束之前最后调用,可以捕获主函数中的异常)
	defer func() {
		panic("3")
		err := recover() // recover() 捕获panic异常,获得程序执行权。
		fmt.Println("4") // recover()后的内容会正常打印
		if err != nil {
			fmt.Println(err) // runtime error: index out of range
		}
	}()

	index := 10
	array[index] = 10 // 会抛出panic异常 (数组下标越界)

	fmt.Println("5") // 异常之后的内容不会打印
}

运行结果如下:

:go run main.go
1
3
2
6
循环嵌套的函数调用
package main

import "fmt"

var times int = 2

func fun4() {
	fmt.Println("fun4")
	fun1()
}

func fun3() {
	fmt.Println("fun3")
}

func fun2() {
	fmt.Println("fun2")
	fun3()
	panic("fun2-painc")
}

func fun1() {
	fmt.Println("fun1")

	defer func() {
		err := recover()
		if err != nil {
			fmt.Println(err)
		}
		times--
		if times != 0 {
			fun4()
		}
	}()

	fun2()
}

func main() {
	fun1()
}

运行结果如下:

./main.go:31:14: syntax error: unexpected !=, expecting {
:go run main.go
fun1
fun2
fun3
fun2-painc
fun4
fun1
fun2
fun3
fun2-painc
发布了248 篇原创文章 · 获赞 13 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/LU_ZHAO/article/details/105062790