コード実行エラーによりランタイム層によってスローされたパニック クラッシュであっても、アクティブにトリガーされたパニック クラッシュであっても、遅延と回復を使用してエラーのキャプチャと回復を実現できます。コードが発生した後にクラッシュする可能性があるため、実行を続行します。
Go には例外システムがありません。パニックを使用してダウンタイムをトリガーすることは、他の言語で例外をスローするのと似ているため、recover のダウンタイム回復メカニズムは try/catch メカニズムに対応します。
プログラムがクラッシュしても実行を継続できるようにする
次のコードは、ProtectRun() 関数を実装します。この関数は、クロージャの後に匿名関数または実行関数を渡します。受信関数が何らかの形式でパニックになった場合、クラッシュのエラーを出力することができ、同時に後続のコードはプロセス全体をクラッシュさせることなく実行を継続できます。
保護された実行関数:
package main import ( "fmt" "runtime" ) // 崩溃时需要传递的上下文信息 type panicContext struct { function string // 所在函数 } // 保护方式允许一个函数 func ProtectRun(entry func()) { // 延迟处理的函数 defer func() { // 发生宕机时,获取panic传递的上下文并打印 err := recover() switch err.(type) { case runtime.Error: // 运行时错误 fmt.Println("runtime error:", err) default: // 非运行时错误 fmt.Println("error:", err) } }() entry() } func main() { fmt.Println("运行前") // 允许一段手动触发的错误 ProtectRun(func() { fmt.Println("手动宕机前") // 使用panic传递上下文 panic(&panicContext{ "手动触发panic", }) fmt.Println("手动宕机后") }) // 故意造成空指针访问错误 ProtectRun(func() { fmt.Println("赋值宕机前") var a *int *a = 1 fmt.Println("赋值宕机后") }) fmt.Println("运行后") }
コードの説明:
行 9 はエラーを説明する構造体を宣言し、メンバーは間違った実行関数を保存します。
行 17 は、クロージャの実行を遅らせるために defer を使用しています。パニックがクラッシュを引き起こすと、ProtectRun() 関数は実行を終了し、defer の後のクロージャが呼び出されます。
20 行目で、recover() は、panic によって渡されたパラメーターを取得します。
行 22、switch を使用して、err 変数に対して型アサーションを実行します。
行 23、エラーが、NULL ポインター アクセス、0 による除算など、ランタイム層によってスローされたランタイム エラーである場合、ランタイム エラーを出力します。
行 25、その他のエラーは、渡されたエラー データを出力します。
44 行目では、panic を使用して手動でエラーを発生させ、情報を含む構造体を渡します。このとき、recover は構造体の情報を取得して出力します。
行 57 は、コード内の null ポインター割り当てによって引き起こされるエラーをシミュレートしています。このとき、エラーはランタイム層によってスローされ、ProtectRun() 関数のcover() 関数によってキャプチャされます。
パニックと回復の関係
パニックと遅延の組み合わせには次の特徴があります。
パニックが発生しても回復が発生しない場合、プログラムがクラッシュします。
パニックおよびリカバリ キャプチャを使用すると、プログラムはクラッシュしません。対応する遅延を実行した後、クラッシュ ポイントから現在の関数を終了し、実行を続行します。
golang の詳細については、PHP 中国語 Web サイトの golang チュートリアル 列に注目してください。
以上がgolang での予期しないクラッシュを防ぐ方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。