deferはクリーンアップをスケジュール、panicはランタイムクラッシュをトリガー(本当に例外的な場合)、recoverはpanicをキャッチしてプログラムのクラッシュを防ぐことができます。
defer — 関数が戻るときに実行するコールをスケジュール
{
f, err := os.Open()
err != { err }
f.Close()
}
deferはクリーンアップをスケジュール、panicはランタイムクラッシュをトリガー(本当に例外的な場合)、recoverはpanicをキャッチしてプログラムのクラッシュを防ぐことができます。
{
f, err := os.Open()
err != { err }
f.Close()
}
deferは関数が戻るときにコール実行をスケジュール — どのような戻り方でも(通常の戻り、エラー、またはpanic)。これはクリーンアップを保証するイディオマティックな方法です:ファイルのクローズ、ミューテックスのアンロック、接続のクローズ — 取得の直後に配置すれば、忘れることがありません。
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
// prints: 3, 2, 1 — last deferred, first executed (stack order)
func mustPositive(n int) {
if n < 0 {
panic("negative not allowed") // stops normal execution, unwinds the stack
}
}
// panic runs deferred functions as it unwinds, then crashes the program (with a stack trace)
panicは通常のフローを停止してコールスタックをアンワインド(その過程でdeferされた関数を実行)し、最終的にプログラムをクラッシュさせます。これはプログラマエラー / 回復不可能な状態(範囲外、nilデリファレンス、不可能な状態)用です — 通常のエラー(返されたerror値を使用)用ではありません。
func safeProcess() {
defer func() {
if r := recover(); r != nil { // recover() returns the panic value
fmt.Println("recovered from:", r) // handle it; program continues
}
}()
panic("something broke") // this panic is caught by the recover above
}
// safeProcess returns normally instead of crashing
recoverはpanicしているゴルーチンの制御を取り戻します — しかしdefer関数内でのみ機能。稀に使用されます。例えば、単一のリクエストハンドラが全サーバーをクラッシュさせるのを防ぐため。
Normal/expected failures (file missing, bad input, validation) → return an error value
panic/recover → reserve for TRULY exceptional cases (bugs, unrecoverable states)
and boundaries (e.g. a server recovering so one bad request doesn't kill the process)
deferは確実なクリーンアップのための本質的でイディオマティックなGo機能です — リソース解放を取得のすぐ後に配置し、すべての戻りパス(panicを含む)で実行されることを確保するため、ファイル、ロック、接続の漏洩をはるかに確実に防ぎます。
そのLIFO順序を理解することも重要です。panic/recoverは例外のようなメカニズムを提供しますが、重要な原則はGoが本当に例外的で回復不可能な状況のためにそれらを予約していることです — 通常のエラーは常に値として返され、チェックされるべきです。
panic/recoverを一般的な例外処理として誤用することは、イディオマティックではなく、例外ベースの言語から来た開発者の一般的な間違いです。
deferを使う場合(常に、クリーンアップ用)、errorを戻す場合(通常の失敗)、panic/recoverを使う場合(稀、例外的、または境界で)を知ることは、正しくイディオマティックなGoを書くためにそして頻出のインタビュートピックとして基本的です。