Go 言語のcrash (panic) – プログラムが終了する

Go 言語のクラッシュ (パニック) - プログラムが終了する

 
 
Go 言語の型システムはコンパイル時に多くのエラーを検出しますが、範囲外の配列アクセス、null ポインター参照など、一部のエラーは実行時にのみチェックできます。これらの実行時エラーはダウンタイムを引き起こします。

 

ダウンタイムはあまり良いことではありません。お金を引き出すときに ATM マシンのブルー スクリーンに遭遇したくないのと同じように、エクスペリエンスが停止し、サービスが中断される可能性があります。ただし、ダウンタイムによってプログラムが停止しない場合は、損失が発生すると、ユーザーは金銭、時間、さらには命に至るまで、より大きな代償を支払うことになるため、ダウンタイムは損失を食い止める合理的な方法となる場合があります。

一般に、ダウンタイムが発生すると、プログラムは動作を中断し、ゴルーチン(最初はスレッドとして理解できます)内の遅延した関数(延期機構)を即座に実行し、プログラムがクラッシュしてログ情報を出力します。情報には、パニック値と関数呼び出しのスタック トレースが含まれます。パニック値は通常、何らかのエラー メッセージです。

各ゴルーチンのログ情報には、パニック発生時の対応する関数呼び出しスタック トレース情報が含まれます。通常、問題を特定するためにプログラムを再度実行する必要はありません。ログ情報は十分な診断根拠を提供します。問題レポートに記入していただくと、通常、ダウンタイムとログ情報が一緒に記録されます。

Go 言語のパニック メカニズムは他の言語の例外と似ていますが、パニックに適用されるシナリオは多少異なります。パニックはプログラムのクラッシュを引き起こす可能性があるため、パニックは通常、プログラム内のロジックの不一致などの重大なエラーに使用されます。クラッシュはコードにバグがある可能性があることを示しているため、ほとんどのバグに対して、パニックではなく Go 言語が提供するエラー メカニズムを使用する必要があります。

ダウンタイムを手動でトリガーする

Go 言語は、プログラム内でダウンタイムを手動でトリガーしてプログラムをクラッシュさせることができるため、開発者は時間内にエラーを発見し、起こり得る損失を減らすことができます。

Go 言語のプログラムがクラッシュすると、スタックやゴルーチンの情報がコンソールに出力されるので、どこでエラーが発生したかを知ることもできて便利です。

package main

func main() {
    panic("crash")
} 

コードが実行され、次の出力が表示されてクラッシュします。

panic: crash

goroutine 1 [running]:
main.main()
    D:/code/main.go:4 +0x40
exit status 2

上記のコードは、クラッシュを引き起こすために組み込み関数 Panic() のみを使用しています。panic() の宣言は次のとおりです。

 func panic(v interface{})    //panic()の引数は任意の型にできます。 

依存関係の実行に必要なリソースが不足している場合に、ダウンタイムをアクティブにトリガーします。

regexp は Go 言語の正規表現パッケージです。正規表現は使用する前にコンパイルする必要があり、コンパイルが成功して正規表現が使用可能であることを示す必要があります。

コンパイルされた正規表現関数には次の 2 種類があります。

1)func Compile(expr string) (*Regexp, error)

正規表現をコンパイルし、エラーが発生した場合はコンパイルエラーを返し、Regexpをnilとして返すため、コンパイルエラーを取得して実行を継続しながら処理する環境に適した関数です。

2) func MustCompile(str string) *Regexp

正規表現のコンパイル中にエラーが発生した場合、パニックを使用してシャットダウンをトリガーします。この機能は、正規表現エラーを処理せずに正規表現が直接使用される状況に適しています。

MustCompile のコードは次のとおりです。

 func MustCompile(str string) *Regexp {
    regexp, error := Compile(str)
    if error != nil {
        panic(`regexp: Compile(` + quote(str) + `): ` + error.Error())
    }
    return regexp
} 

コードの説明は次のとおりです。

  • 行 1、正規表現関数エントリをコンパイルし、正規表現を含む文字列を入力し、正規表現オブジェクトを返します。
  • 2 行目の Compile() は、正規表現をコンパイルするためのエントリ関数であり、コンパイルされた正規表現オブジェクトとエラーを返します。
  • 3 行目と 4 行目では、エラーが発生した場合に、panic() を使用してシャットダウンをトリガーすると判断します。
  • 6 行目では、エラーがない場合に正規表現オブジェクトが返されます。

手動でシャットダウンしてエラーを報告する方法は、怠惰な方法ではありません。代わりに、エラーを迅速に報告し、プログラムを終了して実行を継続し、より大きなエラーの発生を防ぐことができます。ただし、ダウンタイムを使用するのは良い設計手法ではありません。したがって、ニーズに応じてエラー報告にダウンタイムを使用するかどうかを決定する必要があります。

ダウンタイム中にステートメントの遅延実行をトリガーする

Panic() によって引き起こされるダウンタイムが発生すると、panic() の後のコードは実行されませんが、panic() 関数の前に実行された defer ステートメントは、ダウンタイムが発生したときに引き続き有効になります。次のコードを参照してください。

package main

import "fmt"

func main() {
    defer fmt.Println("ダウンタイム後に行うこと 1")
    defer fmt.Println("ダウンタイム後に行うこと 2")
    パニック("「ダウンタイム」")
} 

コード出力は次のとおりです。

ダウンタイム後に行うこと 2
ダウンタイム後に行うこと 1
panic: 「ダウンタイム」

goroutine 1 [running]:
main.main()
    D:/code/main.go:8 +0xf8
exit status 2

コードの説明:

  • 6 行目と 7 行目では、defer ステートメントを使用して 2 つのステートメントを延期しています。
  • 8号線で事故が発生。

ダウンタイムの前に、defer ステートメントが最初に実行されます。7 行目の defer はダウンタイム後に実行されるため、この defer はダウンタイムの前に最初に処理され、次に 6 行目の defer に対応するステートメントが処理されます。 used ダウンタイムが発生する前にダウンタイム情報を処理します。

 

「 Go 言語のクラッシュ (パニック) – プログラムが終了する」についてわかりやすく解説!絶対に観るべきベスト2動画

【たった1時間で学べる】Go言語のプログラミング初心者向けの超入門講座【文字書き起こし、ソースコードも完全無料!】
はじめてのGolang Part2 Webフレームワーク Gin 前編