本文へスキップ
BecomeCoder

Goコース · 第4章 関数とエラー処理 · レッスン16

defer ― 後始末を予約する

ブラウザで完結

導入

ファイルを開いたら閉じる、という「最後に必ずやりたい後始末」を書き忘れないための仕組みが defer(ディファー) です。

説明

defer を付けた関数呼び出しは、いまの関数が終わる直前に必ず実行されます。

package main

import "fmt"

func main() {
    defer fmt.Println("3. 後始末(defer)")

    fmt.Println("1. 処理を開始")
    fmt.Println("2. 処理を実行")
    // main が終わる直前に defer が動く
}

実行結果:

1. 処理を開始
2. 処理を実行
3. 後始末(defer)

defer は書いた場所で実行されず、関数の出口まで先送りされます。ファイルを開いた直後に defer file.Close() と書いておけば、途中でどこから return しても閉じ忘れません。実務では次のようなパターンで多用します。

f, err := os.Open("data.txt")
if err != nil {
    return err
}
defer f.Close() // この関数を抜けるとき、必ず閉じる

やってみよう

defer を付けた行が、書いた位置ではなく最後に実行される点を出力の順番で確かめましょう。「開く直後に閉じる予約をする」ことで、後始末の書き忘れを防げます。

実際に動かしてみよう

下のエディタにGoを書いて「実行」を押すと、学習用シミュレータが fmt の出力を表示します(本物のGoコンパイラではなく、教材の範囲を再現した軽量エンジンです)。スライス・マップ・構造体・インターフェース・goroutine/channel なども動きます。本文の例を書き換えて動かしてみましょう(並行処理の実行順は決定的に再現しているため、本物のインターリーブとは異なる場合があります)。

Go — ブラウザ内で実行(学習用シミュレータ)

Goの教材サブセットを動かす学習用シミュレータを読み込みます(本物のGoコンパイラではなく、動きを再現した軽量な自作エンジンです)。
スクロールして表示された時点でも自動で読み込まれます。