カテゴリ: Go言語 更新日: 2025/07/13

Go言語のdeferを関数で使うテクニックと応用例!初心者でも理解できる遅延実行の使い方

Go言語のdeferを関数で使うテクニックと応用例
Go言語のdeferを関数で使うテクニックと応用例

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

生徒

「Go言語を勉強してると『defer』っていうのが出てきました。これは何に使うんですか?」

先生

「いいところに気がついたね。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で指定したfmt.Println("最後に実行されます")は、main関数の処理が終わる直前に実行されています。

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()と書くことで、関数の最後に自動でファイルを閉じてくれるため、書き忘れを防げます。

4. deferの実行順に注意しよう

4. deferの実行順に注意しよう
4. deferの実行順に注意しよう

複数のdeferを使うと、「最後に書いたものが最初に実行」されます。つまり、後入れ先出し(LIFO)という順序になります。


package main

import "fmt"

func main() {
    defer fmt.Println("1番最後")
    defer fmt.Println("2番目")
    defer fmt.Println("最初に実行される")
}

このコードの出力結果は次のとおりです:


最初に実行される
2番目
1番最後

deferは書いた順ではなく逆順に実行されることを覚えておきましょう。

5. 関数でdeferを活用するテクニック

5. 関数でdeferを活用するテクニック
5. 関数でdeferを活用するテクニック

関数内でdeferを使うことで、処理の片付けやログ出力などを効率よく行えます。次の例は、「処理の開始」と「処理の終了」をログとして出力するものです。


package main

import "fmt"

func main() {
    process()
}

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

    fmt.Println("データを処理しています...")
}

このように、関数の入り口と出口に関係する処理を簡潔に書けるのが、deferの大きな利点です。

6. deferの注意点と使いすぎのデメリット

6. deferの注意点と使いすぎのデメリット
6. deferの注意点と使いすぎのデメリット

便利な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)とは?便利な特徴と使い方を初心者向けにやさしく解説!