1. 集計の処理ログ
  2. 別の処理名
コース一覧
Go入門
deferで後始末

Go入門

変数とゼロ値、Go唯一のループであるfor、複数戻り値とエラー処理、スライスとマップ、構造体とメソッド、ゴルーチンによる並行処理、net/httpによるAPI開発まで、Goの基礎を、毎レッスン実際にコードを書き、フリマアプリのAPIをGoで作りながら学びます。

1
Hello, Go
01. Goとは15分
02. 実行してみる15分
03. packageとmain15分
04. fmtで出力する15分
05. go buildと1バイナリ15分
06. つくる: 起動バナー20分
07. 第1章クイズ10分
2
変数と型
01. varで宣言する15分
02. := の短縮宣言15分
03. ゼロ値(Goならでは)15分
04. 基本の型15分
05. 暗黙変換なし15分
06. 定数とiota15分
07. つくる: 商品データ表示20分
08. 第2章クイズ10分
3
制御構文(forしかない世界)
01. Goのif15分
02. forしかない世界15分
03. forの七変化15分
04. Goのswitch15分
05. 定番: FizzBuzz15分
06. ループで集計15分
07. つくる: 商品集計20分
08. 第3章クイズ10分
4
関数とエラー処理
01. funcで関数を作る15分
02. 複数戻り値(Goならでは)15分
03. if err != nil(Goの心臓)15分
04. エラーを作る15分
05. deferで後始末15分
06. つくる: 検証つき関数群20分
07. 第4章クイズ10分
5
スライスとマップ
01. 配列15分
02. スライス15分
03. appendで育てる15分
04. rangeで走査する15分
05. マップ15分
06. カンマokイディオム15分
07. つくる: 検索と集計20分
08. 第5章クイズ10分
6
構造体とメソッド
01. 構造体15分
02. 初期化とフィールド15分
03. メソッド15分
04. ポインタレシーバ20分
05. New関数の慣習15分
06. 構造体のスライス15分
07. つくる: Itemで再設計20分
08. 第6章クイズ10分
7
ゴルーチンと並行処理のさわり
01. ゴルーチン15分
02. チャネル20分
03. 待ち合わせ20分
04. 並行の落とし穴20分
05. つくる: 並行集計20分
06. 第7章クイズ10分
8
Web API(net/http)
01. サーバーを立てる20分
02. ハンドラ関数20分
03. JSONを返す20分
04. ルーティング20分
05. 一覧API20分
06. 詳細APIと40420分
07. 出品API20分
08. つくる: API主要部完成25分
09. 第8章クイズ10分
9
総合制作
01. 仕様互換を仕上げる25分
02. Node版と差し替える25分
03. 1バイナリでデプロイ25分
04. 自由拡張25分
05. 完成と次のステップ20分

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. 最後に余分な改行を付けない

入出力例

processLog("集計") → "[開始] 集計 処理中 [終了] 集計" processLog("検索") → "[開始] 検索 処理中 [終了] 検索"

ヒント

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

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

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

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

関連レッスン

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

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

  • 第4章クイズ

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

  • 配列

    長さが型の一部である配列を知り、固定長の並びを扱えるようになります。

  • 構造体

    関連するデータを1つの型にまとめ、Item構造体を定義できるようになります。

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

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

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

メモ

deferで後始末

⌘S で保存