カテゴリ: Go言語 更新日: 2025/06/26

Go言語のdefer文の基本!処理の後に必ず実行する仕組みとは

Go言語のdefer文の基本!処理の後に必ず実行する仕組みとは
Go言語のdefer文の基本!処理の後に必ず実行する仕組みとは

先生と生徒の会話形式で理解しよう

生徒

「Go言語を勉強していて、deferっていうのを見かけたんですけど、何に使うんですか?」

先生

deferは、ある関数の処理が終わった後に実行したい処理を、あらかじめ予約しておくためのキーワードなんです。」

生徒

「後で実行って、どんなときに便利なんですか?」

先生

「たとえば、ファイルを開いて作業した後に必ず閉じたいときや、プログラムの後始末を忘れずに行いたいときなどに便利ですよ。では、詳しく説明していきましょう!」

1. defer文とは?Go言語の基本キーワード

1. defer文とは?Go言語の基本キーワード
1. defer文とは?Go言語の基本キーワード

Go言語のdefer文(デファー文)は、特定の処理を「関数の最後」に実行したいときに使う構文です。「後回しにする」という意味を持っていて、直訳すると「延期する」ということになります。

つまり、関数の中でdeferを使っておくと、その関数が終了する直前に指定した処理を必ず実行してくれます。これは、エラーが起きたときでも必ず実行されるので、後片付けや重要な終了処理などにとても便利です。

2. defer文の基本的な使い方を覚えよう

2. defer文の基本的な使い方を覚えよう
2. defer文の基本的な使い方を覚えよう

まずは、簡単なコードでdeferの基本的な使い方を確認しましょう。


package main

import "fmt"

func main() {
    fmt.Println("処理を開始します")
    defer fmt.Println("最後に実行される処理です")
    fmt.Println("メインの処理を実行中")
}

このコードを実行すると、以下のような順番で出力されます。


処理を開始します
メインの処理を実行中
最後に実行される処理です

deferを使った部分は、関数の最後に実行されていることがわかりますね。

3. ファイル操作や後始末で活躍するdefer文

3. ファイル操作や後始末で活躍するdefer文
3. ファイル操作や後始末で活躍するdefer文

deferは、プログラムの「片付け」や「後始末」を忘れないためにとても役立ちます。特に、ファイルやネットワーク、データベースなどを扱うときには必ず使う習慣をつけましょう。

たとえば、ファイルを開いた後に確実に閉じたいときは次のように書きます。


package main

import (
    "fmt"
    "os"
)

func main() {
    file, err := os.Open("sample.txt")
    if err != nil {
        fmt.Println("ファイルを開けませんでした:", err)
        return
    }
    defer file.Close()

    fmt.Println("ファイルを開いて処理中…")
}

defer file.Close()と書いておけば、関数が終わるときにfile.Close()が自動で実行されます。これにより、ファイルの閉じ忘れを防げます。

4. 複数のdefer文はどうなる?実行順序もチェック

4. 複数のdefer文はどうなる?実行順序もチェック
4. 複数のdefer文はどうなる?実行順序もチェック

deferは複数回使うこともできます。ただし、実行される順番に特徴があり、「後に書いたdeferが先に実行される(LIFO)」というルールになっています。

次のコードを見てください。


package main

import "fmt"

func main() {
    defer fmt.Println("1つ目のdefer")
    defer fmt.Println("2つ目のdefer")
    fmt.Println("処理中...")
}

実行結果はこのようになります。


処理中...
2つ目のdefer
1つ目のdefer

このように、後からdeferで指定したものが先に実行されるため、「積み重ねた順に逆から」実行されると覚えておくといいでしょう。

5. 関数の中でパニック(エラー)が起きてもdeferは実行される

5. 関数の中でパニック(エラー)が起きてもdeferは実行される
5. 関数の中でパニック(エラー)が起きてもdeferは実行される

deferの強力な特徴は、関数の途中でエラーが発生しても、必ず実行されることです。これによって、安心して後始末を任せることができます。

次の例では、意図的にパニックを起こしていますが、deferはちゃんと実行されています。


package main

import "fmt"

func main() {
    defer fmt.Println("プログラム終了処理中…")

    fmt.Println("処理開始")
    panic("何か問題が発生しました!")
}

出力は次のようになります。


処理開始
プログラム終了処理中…
panic: 何か問題が発生しました!

このように、エラー(パニック)が起きてもdeferの処理はきちんと呼ばれます。

6. defer文の使い方に注意するポイント

6. defer文の使い方に注意するポイント
6. defer文の使い方に注意するポイント

便利なdeferですが、次のような注意点もあります。

  • 使いすぎるとコードが読みにくくなる:必要以上に多用すると、実行されるタイミングがわかりにくくなります。
  • 実行されるのは「関数の終了時」:ループの中で使っても、関数が終わるまで実行されません。
  • 実行コストがある:毎回呼び出し情報を保存するため、軽い処理に使いすぎないようにしましょう。

これらを意識して、deferは「確実に実行したい後始末」に使うのがベストです。

関連記事:
カテゴリの一覧へ
新着記事
Go言語の関数でエラーハンドリングする基本的な方法
Go言語のスライス・マップ・配列をまとめて比較してみよう!初心者でもわかる使い分けの基本
Go言語の条件分岐の見やすい書き方を徹底解説!初心者でもわかるif文の使い方
Go言語とは何か?初心者向けに特徴・できること・インストール手順までやさしく解説
人気記事
No.1
Java&Spring記事人気No1
Swift Playgroundの使い方を完全解説!初心者に最適な学習環境の始め方
No.2
Java&Spring記事人気No2
Go言語で条件式を1行で書くコツ!三項演算子の代替と短縮記法
No.3
Java&Spring記事人気No3
Swift開発環境の構築方法を徹底解説!Xcode・Windows・Linux対応
No.4
Java&Spring記事人気No4
Kotlinのデータクラス(data class)とは?便利な特徴と使い方を初心者向けにやさしく解説!