Восстановить и продолжить цикл, если возникнет паника Голанг - PullRequest
0 голосов
/ 30 июня 2018

, поэтому мой случай довольно сложный, но для постановки вопроса в чистом и понятном контексте я использую простой цикл for, который начинается с 0 и идет до 10. Теперь я пытаюсь сделать, когда i becomes equal to 2 программа будет рассматривать это как паника. Он перейдет в состояние восстановления с помощью 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)
    }

}

Может ли это быть достижимо на ходу, например, когда возникает паника, мы можем восстановить и завершить наш цикл?

1 Ответ

0 голосов
/ 30 июня 2018

Вы можете сделать это, если тело цикла выполняется как функция, анонимная или именованная, и в этой функции вы используете отложенную функцию для восстановления.

Вот как это выглядит с анонимными функциями:

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 .

...