コース一覧
    Go基礎:制御構文
    deferで後始末

    Go基礎:制御構文

    Goの分岐、反復、関数、エラー処理を体系的に学ぶ基礎コースです。

    1
    制御構文(forしかない世界)
    01. Goのif15分
    02. forしかない世界15分
    03. forの七変化15分
    04. Goのswitch15分
    05. 定番: FizzBuzz15分
    06. ループで集計15分
    07. つくる: 商品集計20分
    08. 第3章クイズ10分
    2
    関数とエラー処理
    01. funcで関数を作る15分
    02. 複数戻り値(Goならでは)15分
    03. if err != nil(Goの心臓)15分
    04. エラーを作る15分
    05. deferで後始末15分
    06. つくる: 検証つき関数群20分
    07. 第4章クイズ10分

    deferで後始末

    後で実行する予約

    Go

    func process() {
    	fmt.Println("開始")
    	defer fmt.Println("終了")
    	fmt.Println("処理中")
    }

    プレーンテキスト

    開始
    処理中
    終了

    defer を付けた行は、その場では実行されません。関数を抜けるときに実行されます。書いた場所は2行目なのに、出力は最後に来ます。

    何のためにあるのか

    開いたものを閉じる、確保したものを返す、という後始末のためです。

    Go

    f := openFile("items.csv")
    defer f.Close()
    
    // この先どこで return しても、Close は必ず呼ばれる

    後始末を開く処理のすぐ下に書けるのが利点です。関数の最後に書くと、途中に return を足したときに素通りされます。defer ならその心配がありません。

    第8章でファイルやリクエストの本文を扱うとき、この形が何度も出てきます。

    複数書くと逆順になる

    Go

    defer fmt.Println("1番目")
    defer fmt.Println("2番目")
    defer fmt.Println("3番目")

    プレーンテキスト

    3番目
    2番目
    1番目

    後に書いたものから実行されます。積み上げたものを上から降ろす順番です。

    開いた順に閉じると困ることがあるので、この順序になっています。A を開いて B を開いたなら、閉じるのは B が先であるべき、という考え方です。

    引数はその場で確定する

    ここが最も間違えやすい点です。

    Go

    count := 1
    defer fmt.Println(count)   // 1 が出る
    count = 2

    実行されるのは最後ですが、引数の値は defer を書いた時点で決まります。後で count を変えても、出力は 1 のままです。

    変わってほしいなら、関数ごと囲みます。

    Go

    count := 1
    defer func() { fmt.Println(count) }()   // 2 が出る
    count = 2

    中の count は実行時に読まれるので、変更が反映されます。末尾の () は「この場で呼び出す形にしておく」という意味で、これを書き忘れると何も起きません。

    第7章のゴルーチンで、この違いがそのまま出てきます。

    要件

    1. defer を使って終了の行を予約する
    2. [開始] 名前 処理中 [終了] 名前 の3行を \n でつないで返す
    3. 最後に余分な改行を付けない

    ヒント

    戻り値に名前を付けます。`func processLog(name string) (result string) {` と書くと、defer の中から `result` を書き換えられます

    `defer func() { ... }()` の形で囲むと、中身は関数を抜けるときに実行され、そのときの `log` の値が読まれます

    末尾の `()` を忘れないでください。書かないと予約されるだけで実行されません

    生田 陸人
    監修生田 陸人
    ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
    編集 ゆめさく編集部·公開 2026/08/10

    関連レッスン

    • つくる: 検証つき関数群

      第4章の知識で出品の検証と計算をerror付きの関数にまとめられるようになります。

    • 第4章クイズ

      関数、複数戻り値、error、defer についての理解を確認します。

    • エラーを作る

      errors.Newとfmt.Errorfで自分のエラーを返し、理由の分かる失敗を作れるようになります。

    • if err != nil(Goの心臓)

      errorを受けて分岐する型を身につけ、失敗を無視しないコードを書けるようになります。

    このレッスンに出てくる用語

    意味があいまいなまま進んだ語は、ここから読み直せます。

    • 関数処理に名前を付けて再利用できる単位
    • 処理計算や代入を表す長方形
    • リクエストWeb 通信の基本単位、ブラウザの問い合わせとサーバーの返答
    • 引数位置引数=順番で渡す。
    main.go
    エディタを読み込んでいます

    メモ

    deferで後始末

    ⌘S で保存