所以我的情况很复杂,但是为了在干净的环境中提问,我使用的是从0开始到10的简单for循环。它会使用defer进入恢复状态,然后在恢复循环后恢复。

因此,所需的输出应该是这样的:

0
1
panic occured: got 2
3
4
.
.
.
.
.
10

我得到的实际输出
0
1
panic occured got:  got 2

代码块:
package main

import "fmt"

func main() {
    goFrom1To10()
}

func goFrom1To10() {
    defer recovery()
    for i := 0; i <= 10; i++ {

        if i == 2 {
            panic("got 2")

        }
        fmt.Println(i)
    }

}

func recovery() {
    if r := recover(); r != nil {
        fmt.Println("panic occured: ", r)
    }

}

这样就可以实现吗,例如当发生 panic 时,我们可以恢复并完成循环了吗?

最佳答案

如果将循环的主体作为一个函数(匿名函数或命名函数)执行,则可以执行此操作,然后在该函数中使用延迟函数进行恢复。

匿名函数的外观如下:

func goFrom1To10() {
    for i := 0; i <= 10; i++ {
        func() {
            defer func() {
                if r := recover(); r != nil {
                    fmt.Println("panic occured: ", r)
                }
            }()

            if i == 2 {
                panic("got 2")
            }
            fmt.Println(i)
        }()
    }
}

输出(在Go Playground上尝试):
0
1
panic occured:  got 2
3
4
5
6
7
8
9
10

如果将其移至命名函数,它将更好,更容易理解:
func goFrom1To10() {
    for i := 0; i <= 10; i++ {
        task(i)
    }
}

func task(i int) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("panic occured: ", r)
        }
    }()

    if i == 2 {
        panic("got 2")
    }
    fmt.Println(i)
}

输出是相同的。在Go Playground上尝试这个。

关于for-loop - 如果发生 panic ,请恢复并继续循环,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51113193/

10-10 13:56
查看更多