Go程式在for迴圈中panic時仍可繼續執行的作法如下。
例如下面for迴圈中發生panic時程式即結束,迴圈剩下的部分未繼續執行。
main.go
package main
import (
"fmt"
)
func main() {
for i := 0; i < 5; i++ {
defer func() {
if r := recover(); r != nil {
fmt.Println("recovered", r)
}
}()
if i == 2 {
panic("panic!")
}
fmt.Println(i)
}
}
執行結果如下,執行到i == 2
時發生panic就停止了。
0
1
recovered panic!
這是因為panic會中斷當前的goroutine並離開函式,recover()
只是捕捉panic,recover執行完仍會離開函式。而上面從頭到尾都只在一個goroutine的main()
函式中執行,所以main()
中發生panic時會先執行defer函式的recover後然後離開main()
。
若要讓for迴圈中發生panic時仍能繼續執行,可用一個函式包裝panic及recover。例如下面用一個匿名函式包裝原本的panic及recover,則panic發生時是跳離所包裝的匿名函式而非main()
函式,跳離後再下一次迴圈又開始了新的匿名函式來執行。
main.go
package main
package main
import (
"fmt"
)
func main() {
for i := 0; i < 5; i++ {
func() {
defer func() {
if r := recover(); r != nil {
fmt.Println("recovered", r)
}
}()
if i == 2 {
panic("panic!")
}
fmt.Println(i)
}()
}
}
執行印出如下,panic及recover後迴圈仍繼續進行。
0
1
recovered panic!
3
4
沒有留言:
張貼留言