defer
式の実行を、それを囲む関数が戻るまで遅らせる言語機能。早期リターンやパニックがあっても、後始末が確実に行われる。元祖はGo(2009年)で、ZigやSwiftにもある。try-finallyやRAIIの代替である。
Goの古典例:file, _ := os.Open(...) の直後に defer file.Close() と書く。関数の途中でエラーリターンしても、closeは必ず実行される。複数のdeferはLIFO(スタック)順に実行される。よくある落とし穴は、ループ内の defer file.Close() だ。closeは関数が終わるまで溜まり続け、ファイルハンドルがリークする。内側の関数に切り出して直す。Swiftの defer { cleanup() } も同様だ。Zigには defer と、エラーリターン時のみ実行される errdefer がある。現代的なリソース管理のパターンで、「糖衣構文付きのJavaのtry-finally」と読めばよい。