INDEX
deferの概要
遅延実行 Goの予約語 | ||
defer 概要 |
||
|
基本的なdeferの使い方
defer
を使うと、関数が終了する直前に処理を実行できます。
package main
import "fmt"
func main() {
fmt.Println("開始")
defer fmt.Println("遅延実行")
fmt.Println("終了")
}
解説:
defer fmt.Println("遅延実行")
は、関数の最後に実行されるように遅延されます。- 通常の処理は
開始 → 終了
の順で実行されますが、defer
により最後に「遅延実行」が出力されます。
実行結果:
開始 終了 遅延実行
複数のdeferを使用した場合の実行順
defer
を複数使うと、後に登録されたものから順に実行されます(LIFO: 後入れ先出し)。
package main
import "fmt"
func main() {
defer fmt.Println("1番目のdefer")
defer fmt.Println("2番目のdefer")
defer fmt.Println("3番目のdefer")
fmt.Println("メイン処理")
}
解説:
- 最初に「メイン処理」が出力されます。
- その後、最後に登録した
defer
から順番に実行されます(3番目 → 2番目 → 1番目)。
実行結果:
メイン処理 3番目のdefer 2番目のdefer 1番目のdefer
deferを使ったリソースのクリーンアップ
defer
はファイルやデータベース接続のクローズ処理によく使われます。
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Create("example.txt")
if err != nil {
fmt.Println("ファイル作成エラー:", err)
return
}
defer file.Close() // 関数終了時にファイルをクローズ
file.WriteString("Hello, World!")
fmt.Println("ファイルに書き込みました")
}
解説:
defer file.Close()
を使うことで、関数が終了する際にファイルが自動的にクローズされます。- エラーハンドリングとリソース管理を簡潔に記述できるため、
defer
はよく使用されます。
実行結果:
ファイルに書き込みました
panicとrecoverを使ったエラーハンドリング
defer
を利用すると、panic
が発生した場合でもリカバリーできます。
package main
import "fmt"
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("パニックを回復:", r)
}
}()
fmt.Println("通常の処理")
panic("エラー発生!")
fmt.Println("この行は実行されません")
}
解説:
recover()
をdefer
内で使用することで、panic
の回復が可能になります。panic("エラー発生!")
でパニックを発生させても、プログラムがクラッシュせずに処理を続行できます。
実行結果:
通常の処理 パニックを回復: エラー発生!
注意事項
- deferの引数は即時評価される:
defer
に渡す関数の引数は、その時点で評価されるため、後で変更されても影響しない。 - deferは大量に使用しない: LIFOで実行されるため、メモリ消費が増加する可能性がある。
- panicが発生してもdeferは実行される:
defer
を適切に利用すれば、リソースのリークを防ぐことができる。
よくある質問
- Q: deferは必ず実行されますか?
- A: はい。関数が終了する直前に必ず実行されます。ただし、プログラムが
os.Exit()
で終了すると実行されません。 - Q: deferの実行順序はどうなりますか?
- A: 後に指定した
defer
が先に実行される(LIFO: 後入れ先出し)というルールがあります。 - Q: deferの中で関数の戻り値を変更できますか?
- A: はい。名前付き戻り値を使うことで、
defer
の中で値を変更することが可能です。 - Q: deferを使うとどんなメリットがありますか?
- A: 関数終了時に確実に実行されるため、ファイルクローズやロック解除などのリソース管理が簡潔に記述できます。
まとめ
defer
を使うと、関数終了直前に処理を実行できる。- 複数の
defer
を登録すると、後に登録したものから実行される(LIFO順)。 - ファイルのクローズやパニックの回復など、リソース管理に適している。
- 使用しすぎるとメモリ消費が増えるため、適切に利用することが重要。