Defer による戻り値の操作
Go では、defer ステートメントを使用して、周囲の関数が戻った後に関数を実行できます。このメカニズムにより、エラーが発生した場合でもクリーンアップ タスクを処理したり、アクションを実行したりすることができます。ただし、パニックを起こし、defer ステートメントで囲まれた関数からエラー値を返そうとする場合には制限があります。
次のコード スニペットを考えてみましょう。
func getReport(filename string) (rep report, err error) { rep.data = make(map[string]float64) defer func() { if r := recover(); r != nil { fmt.Println("Recovered in f", r) err, _ = r.(error) return nil, err } }() panic("Report format not recognized.") // Remaining function code... }
意図は次のとおりです。 getReport 関数がパニックになった場合にエラーを返すようにします。ただし、遅延関数は周囲の関数の戻り値の数を変更できないため、このアプローチは機能しません。代わりに、既存の戻りパラメータの値のみを変更できます。
この問題に対処するには、defer 関数は新しいエラー値を返そうとするのではなく、err 戻りパラメータを変更する必要があります:
defer func() { if r := recover(); r != nil { fmt.Println("Recovered in f", r) // Find out the exact error type and set err switch x := r.(type) { case string: err = errors.New(x) case error: err = x default: err = errors.New("Unknown panic") } // Invalidate rep rep = nil } }()
この変更により、defer 関数は err 戻りパラメーターを更新し、エラー状態を示すために rep を nil に設定します。これにより、周囲の関数が変更された err 値を返すことができるようになります。
以上がDefer ステートメントを使用してパニック関数の戻り値を操作できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。