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
*/
}