web-technical-blog

web開発に関する技術メモ

Go言語の予約語deferについて

予約語deferを使って、関数の終了時に実行される式を登録できる。
defer文による式は、関数の終了時に「あとで登録された式」から順に評価される

package main

import (
    "fmt"
)

func main() {
    runDefer()
}

func runDefer() {
    /* deferに登録された式は関数の終了時に評価される */
    defer fmt.Println("defer")
    fmt.Println("done")
}

/* 出力結果 */
done
defer
package main

import (
    "fmt"
)

func main() {
    runDefer()
}

func runDefer() {
    defer fmt.Println("1")
    defer fmt.Println("2")
    defer fmt.Println("3")
    fmt.Println("done")
}

/* 出力結果 */
done
3
2
1

defer文が最も活躍する局面は「リソースの解放処理」です。
例えば以下のようなファイルをクローズする際にdeferを使用するみたいです。

file, err := os.Open("/path/to/file")

if err != nil {
    /* ファイルのオープンに失敗したらreturn */
    return
}

/* ファイルのクローズ処理を登録 */
defer file.Close()

/////////////////////////////////////////////
package main

import (
    "fmt"
)

func main() {
    defer func() {
        fmt.Println("A")
        fmt.Println("B")
        fmt.Println("C")
    }() // ←関数呼び出しの形式であることに注意

}

/* 出力結果 */
A
B
C