カテゴリ: Go言語 更新日: 2025/12/18

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

Go言語を基礎からスッキリ学びたい人や、 文法だけでなく「実用的な使い方」まで押さえたい人には、 定番の入門書がこちらです。

基礎からわかるGo言語をAmazonで見る

※ Amazon広告リンク

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言語におけるdeferは、プログラムの後片付けやリソース管理を安全かつ確実に行うための非常に重要な機能であり、初心者の段階で理解しておくと開発が格段にスムーズになります。この記事を通して、deferの基本的な動作、関数の終了時に実行される特徴、複数回使用した場合の逆順実行(LIFO)といった仕組みを丁寧に学ぶことができました。また、実際にファイルを開く処理やログ管理など、実務でよく使われる場面に応用できる知識として身につけられたはずです。

プログラムを書く際には、その時点で開いたリソースが必ず適切に閉じられるようにすることが非常に重要です。たとえば、ファイル、ネットワーク接続、データベース接続など、忘れると大きな問題につながる処理は多く存在します。そのような状況でdeferが役に立ち、関数の最後に自動で実行される後片付け処理として機能します。これにより、コードの見通しが良くなり、安全性も高まるのです。

また、今回の記事の中では、関数内でのdefer活用例、複数のdeferを使用した場合の実行順序、ループ内での使いすぎに注意すべき理由など、実際に使う場面で理解しておきたい応用知識も紹介しました。こうした知識は、Go言語を学ぶ初心者がステップアップするうえで欠かせません。

以下では、今回学んだ内容をさらに深めるために、deferを複数の関数に応用し、ログ出力・エラー処理・複数リソースの管理を組み合わせた少し高度なサンプルコードを掲載します。ぜひ参考にして、実際の開発にも活かしてみてください。

追加サンプルコード:複数リソースとログ管理にdeferを使う応用例


package main

import (
    "fmt"
    "os"
)

// ログを開始・終了で出力する関数
func withLog(processName string) func() {
    fmt.Println("=== 開始:", processName, "===")
    return func() {
        fmt.Println("=== 終了:", processName, "===")
    }
}

// ファイルを安全に処理する関数
func handleFile(path string) {
    defer withLog("ファイル処理")()

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

    defer file.Close()

    fmt.Println("ファイルを安全に扱っています:", path)
}

func main() {
    defer withLog("メイン処理")()

    handleFile("sample.txt")

    fmt.Println("その他の処理を実行中...")
}

このコードでは、ログ出力を管理するためのwithLog関数を使い、関数の開始と終了をわかりやすく記録しています。また、ファイル操作でもdefer file.Close()を使うことで、処理の中断が発生しても確実にリソースが解放されます。

deferを使う最大のメリットは、複雑な処理の中でも「最後に必ず実行したいこと」を自然な形で書ける点です。これにより、コードの保守性が上がり、想定外のエラーが起きてもプログラム全体が安定して動作します。とくに、プロジェクトが大きくなっていくとこうしたリソース管理が重要になるため、初心者のうちから正しい使い方に慣れておくことがとても大切です。

deferは一見すると単純なキーワードですが、理解すればするほど奥深く、さまざまな場面で役に立つ強力な仕組みです。今回学んだことを活かし、より安全で読みやすく、ミスの少ないGo言語のコードを書けるよう意識してみてください。

先生と生徒の振り返り会話

生徒

deferって単純に“最後に動く”だけだと思ってたんですが、応用するとこんなに便利なんですね!」

先生

「その通りです。リソース管理やログ管理に使うと、コードが安全でスッキリしたものになりますよ。」

生徒

「ファイル操作の例はすごくわかりやすかったです。閉じ忘れを防げるのは助かります!」

先生

「実際の開発では“閉じ忘れ”が深刻な問題になることもあるので、deferはとても大切ですよ。」

生徒

「今回のサンプルみたいにログも組み合わせると便利ですね。もっと使いこなせるように練習してみます!」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Go言語のdeferとは何ですか?初心者でも理解できる意味を教えてください

Go言語のdeferとは、処理を“後で実行する”ためのキーワードで、関数の最後に必ず実行したい処理を遅延実行として登録できる仕組みです。主に後片付けやリソース解放に使われます。
カテゴリの一覧へ
新着記事
New1
Go言語
Go言語の短絡評価(ショートサーキット)を使った条件式の工夫をやさしく解説!初心者でも理解できる基本知識
New2
Go言語
Go言語の構造体の初期化パターンとコンストラクタ的関数の書き方を徹底解説!初心者でもわかる基本と実用例
New3
Kotlin
Kotlinの例外処理とキャンセルの連携を完全ガイド!初心者でもわかるCoroutineExceptionHandlerの使い方
New4
Go言語
Go言語のクロージャとは?関数内関数の活用例と仕組み
人気記事
No.1
Java&Spring記事人気No1
Kotlin
KotlinのChannelでデータをやり取りする方法を完全ガイド!初心者にもわかる非同期通信の基本
No.2
Java&Spring記事人気No2
Go言語
Go言語でのDB接続情報を環境変数で管理する方法|初心者でも安全に設定
No.3
Java&Spring記事人気No3
Kotlin
Android Studioのインストール手順と初期設定を初心者向けに完全解説!
No.4
Java&Spring記事人気No4
Kotlin
Kotlinのビルド設定エラーと解決法まとめ!初心者向けGradleトラブル対処ガイド
No.5
Java&Spring記事人気No5
Kotlin
Gradleファイル(build.gradle.kts)の書き方と役割をやさしく解説!Kotlin初心者向け完全ガイド
No.6
Java&Spring記事人気No6
Kotlin
Kotlinでテキスト表示・編集!初心者でもわかるTextViewとEditTextの使い方
No.7
Java&Spring記事人気No7
Kotlin
Kotlin DSLとGroovy DSLの違いをやさしく解説!初心者でもわかるGradleスクリプトの使い分け
No.8
Java&Spring記事人気No8
Swift
Swift Playgroundの使い方を完全解説!初心者に最適な学習環境の始め方

💻 作業効率アップに

ノートPCを縦置きしてデスクを広く。
省スペースで片づく定番スタンド

UGREEN 縦型スタンドをAmazonで見る

※ Amazon広告リンク