Dev Study
Go コース

30. defer — 後始末を予約する(LIFO)

defer を付けた関数呼び出しは、その場では実行されず、現在の関数が return するか終了する直前にまとめて実行されます。ファイルを開いたらすぐ defer f.Close() と書いておけば、どの経路で関数を抜けても確実に閉じられる、というように「後始末を忘れない」ために使います。処理本体と後始末を近くに書けるので読みやすくなります。

defer が複数あるときは、後に書いたものほど先に実行される LIFO(後入れ先出し)の順序になります。下の例では defer を 1, 2, 3 の順に登録していますが、実行は 3, 2, 1 の逆順です。ネストした後始末(開いた順と逆に閉じたい場合など)に都合の良い性質です。

もう一つ大事なのは、defer に渡す関数の引数は defer を書いた時点で評価される点です。あとで変数が変わっても、defer に渡した値は登録時のものが使われます。一方で、クロージャの中で変数を参照していれば実行時の値が反映されます。この違いを押さえておくとハマりにくくなります。

▶ サンプルコードを実行してみよう(自由に書き換えてOK)

Go
公式ドキュメントで詳しく ↗