サーチ…


備考

この記事ではDefer Basicsの知識を前提としています

通常のエラー処理については、エラー処理のトピックを読んでください

パニック

パニックは通常の実行フローを停止し、現在の機能を終了します。制御がスタック上の次の上位関数に渡される前に、遅延呼び出しが実行されます。各スタックの関数は、遅延recover()を使用してパニックが処理されるか、またはパニックがmain()到達してプログラムが終了するまで、遅延呼び出しを終了して実行します。これが起こると、パニックに与えられた引数とスタックトレースがstderrされます。

package main

import "fmt"

func foo() {
    defer fmt.Println("Exiting foo")
    panic("bar")
}

func main() {
    defer fmt.Println("Exiting main")
    foo()
}

出力:

Exiting foo
Exiting main
panic: bar


goroutine 1 [running]:
panic(0x128360, 0x1040a130)
    /usr/local/go/src/runtime/panic.go:481 +0x700
main.foo()
    /tmp/sandbox550159908/main.go:7 +0x160
main.main()
    /tmp/sandbox550159908/main.go:12 +0x120

panicはパラメータとして任意の型を受け入れることに注意することが重要です。

回復する

名前が示すように回復すると、 panicから回復しようとすることができます。通常の実行フローが停止されているので、リカバリ遅延ステートメントで試行する必要あります。 recoverステートメントは、遅延関数エンクロージャー内に直接現れなければなりません。遅延関数呼び出しによって呼び出された関数のリカバリ文は無視されます。プログラムが現在パニックに陥っている場合、 recover()コールは最初のパニックに与えられた引数を返します。プログラムが現在パニックしていない場合、 recover()nilを返します。

package main

import "fmt"

func foo() {
    panic("bar")
}

func bar() {
    defer func() {
        if msg := recover(); msg != nil {
            fmt.Printf("Recovered with message %s\n", msg)
        }
    }()
    foo()
    fmt.Println("Never gets executed")
}

func main() {
    fmt.Println("Entering main")
    bar()
    fmt.Println("Exiting main the normal way")
}

出力:

Entering main
Recovered with message bar
Exiting main the normal way


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow