panic发生时,程序控制权的转移:
package main
import "fmt"
func main() {
fmt.Println("Enter function main.")
caller1()
fmt.Println("Exit function main.")
}
func caller1() {
fmt.Println("Enter function caller1.")
caller2()
fmt.Println("Exit function caller1.")
}
func caller2() {
fmt.Println("Enter function caller2.")
s1 := []int{0, 1, 2, 3, 4}
e5 := s1[5]
_ = e5
fmt.Println("Exit function caller2.")
}
输出:
panic: runtime error: index out of range
Enter function main.
Enter function caller1.
goroutine 1 [running]:
Enter function caller2.
main.caller2()
E:/GoProgram/awsomeproject/src/go语言核心36讲/19错误处理/2.go:20 +0x98
main.caller1()
E:/GoProgram/awsomeproject/src/go语言核心36讲/19错误处理/2.go:13 +0x6d
main.main()
E:/GoProgram/awsomeproject/src/go语言核心36讲/19错误处理/2.go:7 +0x6d
Go 语言的内建函数recover专用于恢复 panic,或者说平息运行时恐慌。recover函数无需任何参数,并且会返回一个空接口类型的值,这里 的recover需要配合defer使用:
package main
import (
"fmt"
"errors"
)
func main() {
fmt.Println("Enter function main.")
defer func(){
fmt.Println("Enter defer function.")
if p := recover(); p != nil {
fmt.Printf("panic: %s\n", p)
}
fmt.Println("Exit defer function.")
}()
// 引发 panic。
panic(errors.New("something wrong"))
fmt.Println("Exit function main.")
/**
输出:
Enter function main.
Enter defer function.
panic: something wrong
Exit defer function.
*/
}
如果一个函数中有多条defer语句,那么那几个defer函数调用的执行顺序是怎样的?
package main
import "fmt"
func main() {
defer fmt.Println("first defer")
for i := 0; i < 3; i++ {
defer fmt.Printf("defer in for [%d]\n", i)
}
defer fmt.Println("last defer")
/**
输出:
last defer
defer in for [2]
defer in for [1]
defer in for [0]
first defer
*/
}