Go言語のdefer文の使い方
Go言語では、defer
というキーワードを使用することで、関数が終了する直前に特定の処理を行うことができます。
使用方法は次のようになります。
func example() {
// なんかの処理
defer func() {
// 関数の最後で実行されるコード
}()
// なんかの処理
}
defer
文は、それが宣言された関数が終了する前に実行されます。関数が正常に終了する場合も、panic(ランタイムエラー)が発生した場合も実行されます。
これは、リソースの解放、ファイルのクローズ、ログの記録など、関数の終了時に必ず行うべき処理を行うために使用されます。
例えば、関数が最後にファイルを開いたとすると、deferの中でそのファイルをクローズするように書くことができます。
これにより、関数が正常に終了した場合も、panicが発生した場合も、必ずファイルがクローズされるようになります。
具体的なコード例
以下に、defer
を使用してファイルを開いてからクローズする例を示します。
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Open("example.txt")
if err != nil {
fmt.Println("Error opening file:", err)
return
}
defer file.Close() // file.Close()は関数の最後で呼び出されます。
// ファイルに対して何か処理をする
data := make([]byte, 100)
count, err := file.Read(data)
if err != nil {
fmt.Println("Error reading file:", err)
return
}
fmt.Println("Read", count, "bytes from file")
}
この例では、main関数で os.Open
を使用して “example.txt”という名前のファイルを開きます。その後、 defer file.Close()
文を使用して、ファイルをクローズする処理を定義します。
これにより、関数が正常に終了した場合も、パニックが発生した場合も、必ずファイルがクローズされるようになります。
また、複数のdeferを書いた場合は、後に書いたdeferから先に実行されます。
package main
func main() {
defer fmt.Println("defer 1")
defer fmt.Println("defer 2")
defer fmt.Println("defer 3")
//defer 1 -> defer 2 -> defer 3 の順で実行される
}
上記のように、deferは後に書いたものから先に実行されるため、リソースの開放などでは先に開いたものから後に開いたものの順番で閉じるようにして使用することが多いです。