カテゴリ: Go言語 更新日: 2026/03/04

Go言語のクロージャとは?関数内関数の活用例と仕組み

Go言語のクロージャとは?関数内関数の活用例と仕組み
Go言語のクロージャとは?関数内関数の活用例と仕組み

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

生徒

「Go言語っていうプログラミングで、クロージャって聞いたんですけど、何なんですか?」

先生

「いい質問ですね。クロージャとは、関数の中で作られた関数のことです。Go言語では関数を他の関数の中で定義して、記憶させることができるんですよ。」

生徒

「えっ?関数の中に関数があるんですか?それって何か便利なんですか?」

先生

「とっても便利ですよ!じゃあ、仕組みと使い方を具体的に見ていきましょう!」

1. クロージャとは?基本の考え方を理解しよう

1. クロージャとは?基本の考え方を理解しよう
1. クロージャとは?基本の考え方を理解しよう

Go言語(Golang)のクロージャとは、関数の中で定義された関数が、外側の関数の変数(環境)を記憶して持ち運べる仕組みのことです。外側で用意した値や状態を、内側の関数が後から参照・更新できます。これは関数を値として扱えるGo言語の特性とセットで理解すると分かりやすく、短いコードで「状態を覚える処理」を書けるのが特徴です。

身近な例に置き換えると、台所の蛇口(内側の関数)は、どの水道管(外側の変数)につながっているかを覚えています。蛇口をひねるたびに、同じ水道管から水(前回の状態を引き継いだ値)が流れてくる、というイメージです。

次の超短い例では、外側で用意した回数カウンタを、内側の関数が覚えて増やし続けます。ここでは「関数が外側の変数をキャプチャして記憶する」点だけを体験できれば十分です。


package main

import "fmt"

func main() {
    counter := func() func() int {
        n := 0
        return func() int {
            n++
            return n
        }
    }()
    fmt.Println(counter()) // 1
    fmt.Println(counter()) // 2
}

このコードでは、内側の無名関数が外側の変数nを覚えています。counter()を呼ぶたびにnが増え、前回の値が次回へ引き継がれます。これがGo言語のクロージャの基本です。キーワードは「関数の内部関数」「外側の変数をキャプチャ」「状態を保つ」「あとから呼んでも覚えている」です。

2. クロージャを使った簡単な例

2. クロージャを使った簡単な例
2. クロージャを使った簡単な例

ここでは、Go言語のクロージャ(関数内関数)が「外側の変数を覚えて使い続ける」様子を、最小のコードで体験します。ポイントは、戻り値として返した無名関数が、外側スコープの変数をキャプチャして、次の呼び出しでも同じ状態を参照できることです。


package main

import "fmt"

func main() {
    adder := createAdder() // 関数を作って受け取る(状態を持つ関数)
    fmt.Println(adder(5))  // 5
    fmt.Println(adder(3))  // 8(前回の合計に3を加算)
    fmt.Println(adder(10)) // 18(合計を覚えている)
}

// 合計を覚えるクロージャを返すファクトリ関数
func createAdder() func(int) int {
    sum := 0                 // 外側の変数(状態)
    return func(x int) int { // 無名関数がsumをキャプチャ
        sum += x
        return sum
    }
}

上のコードでは、createAdder「合計を覚える関数」を返し、返された関数はsumという変数を記憶したまま動きます。呼び出すたびにsumが更新されるため、状態を維持しながら計算を続けることができます。これは、カウンタやスコア加算、累積合計などの処理にそのまま応用できます。

初心者の方は、次の観点で読み解くと理解しやすくなります。

  • 関数を変数に代入できる(adderは「関数」という値)
  • 返された無名関数が外側の変数sum)を覚える(キャプチャ)
  • 呼び出すたびに同じ状態が使われるので結果が積み上がる

このように、Go言語のクロージャは「簡潔なコードで状態を扱う」ための強力な道具です。キーワードは無名関数・変数キャプチャ・状態保持・関数を返すです。

3. 実行結果を確認してみよう

3. 実行結果を確認してみよう
3. 実行結果を確認してみよう

上のプログラムを実行すると、以下のような出力になります。


5
8
18

呼び出すたびに、足した結果が蓄積されているのがわかります。これは、sumの値をクロージャが覚えているからです。

4. なぜクロージャが便利なの?

4. なぜクロージャが便利なの?
4. なぜクロージャが便利なの?

クロージャを使うと、「ある状態を覚えておく関数」を作ることができます。普通の関数は毎回ゼロから計算をしますが、クロージャは前の計算結果を記憶して次に活かすことができます。

これにより、同じ処理を繰り返すような場面や、特定の条件に応じて振る舞いが変わる関数を作るのに非常に役立ちます。

5. 関数を変数のように扱えるGo言語の特性

5. 関数を変数のように扱えるGo言語の特性
5. 関数を変数のように扱えるGo言語の特性

Go言語では、関数も値として変数に代入することができます。これがクロージャを活用するうえでとても重要なポイントです。

関数を変数に入れて、その変数を使って関数を呼び出すことで、まるで特別な処理機能を持った変数のように扱うことができるのです。

6. 複数のクロージャを作るとどうなる?

6. 複数のクロージャを作るとどうなる?
6. 複数のクロージャを作るとどうなる?

では、createAdderをもう一度呼び出したらどうなるでしょうか?実験してみましょう。


package main

import "fmt"

func main() {
    adder1 := createAdder()
    adder2 := createAdder()

    fmt.Println(adder1(1)) // 出力: 1
    fmt.Println(adder1(2)) // 出力: 3

    fmt.Println(adder2(10)) // 出力: 10
    fmt.Println(adder2(20)) // 出力: 30
}

func createAdder() func(int) int {
    sum := 0
    return func(x int) int {
        sum += x
        return sum
    }
}

結果は以下のようになります:


1
3
10
30

adder1adder2は別々のsumを持っていて、お互いの影響を受けません。これが状態を持つ関数の力です。

7. クロージャが使われる場面とは?

7. クロージャが使われる場面とは?
7. クロージャが使われる場面とは?

クロージャは、次のような場面でよく使われます:

  • 何かの処理を段階的に進めたいとき(状態を記憶)
  • 条件に応じて関数の動きを変えたいとき
  • 関数を引数として渡すときに、その関数に特定の値を記憶させておきたいとき

たとえばゲームで「スコアを足していく処理」や「買い物の合計金額を覚えていく処理」などにも使えます。

まとめ

まとめ
まとめ

この記事ではGo言語におけるクロージャについて、その仕組みと活用方法をやさしく解説しました。クロージャは、外側の関数の変数を覚えて利用できる関数内関数のことで、Go言語の大きな特徴の一つです。通常の関数は呼び出すたびに新しい処理を行いますが、クロージャは「状態を保持し続けること」ができます。そのため、累積計算、状態管理、イベント処理、カスタマイズされた処理の作成など、実践的なプログラミングで非常に役立ちます。

さらに、クロージャはGo言語の「関数も値として扱える」という特性と組み合わさることで、柔軟かつ強力なコード設計を可能にします。特にWeb開発やAPI設計、ゲーム開発など多様な場面で利用され、コードの再利用性や拡張性を高めます。たとえば「カウンター機能」や「リスナー関数」などは典型的なクロージャの活用例です。

以下に、もう一度整理したサンプルコードを載せておきます。クロージャが変数を記憶して、呼び出しのたびに異なる結果を返す様子を確認できます。


package main

import "fmt"

func main() {
    counter := createCounter()

    fmt.Println(counter()) // 出力: 1
    fmt.Println(counter()) // 出力: 2
    fmt.Println(counter()) // 出力: 3
}

func createCounter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

この例ではcreateCounterが新しい関数を返し、その関数はcountという外側の変数を覚えています。呼び出すたびにcountが増えていくのは、まさにクロージャの特徴です。このようにクロージャを活用することで、Go言語プログラミングでは状態を扱いやすく、シンプルで明快なコードを実現できます。

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

生徒

「先生、今日の記事でクロージャのことがよく分かりました!Go言語では関数の中に関数を作れて、その関数が変数を覚えてくれるんですよね?」

先生

「その通りです。外側の変数を覚える関数、それがクロージャです。例えばカウンターを作るときや、計算の途中経過を保持したいときにとても便利ですね。」

生徒

「なるほど!普通の関数は呼ぶたびにリセットされるけど、クロージャなら前の状態を持ったまま次に進めるんですね。これならスコア計算や買い物の合計金額を覚えておく処理にも使えそうです!」

先生

「そうですね。Go言語では関数を値として扱えるので、クロージャと組み合わせるとプログラミングの幅がぐっと広がります。Webアプリやゲーム開発、サーバーサイドのAPI処理でもよく使われていますよ。」

生徒

「わあ、すごい!実際にサンプルプログラムを動かしてみたら、呼び出すたびに数字が増えていくのが本当に面白かったです。Go言語のクロージャをもっと練習して、自分のプログラムにも使ってみたいです!」

先生

「素晴らしい意欲ですね。クロージャをしっかり理解すれば、より高度なGo言語プログラミングにも自信を持って取り組めるようになりますよ。」

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

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

※ Amazon広告リンク

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

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

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

Go言語のクロージャとは何ですか?初心者でも理解できる簡単な説明が知りたいです。

Go言語のクロージャとは、関数の中で作られた関数が、外側の関数の変数を覚えて使い続ける仕組みのことです。普通の関数は呼び出すたびに初期化されますが、クロージャは前回の状態を残したまま処理を進められます。そのため、累積計算や状態管理が簡単にできる便利な機能です。

なぜGo言語のクロージャは「関数内関数」と呼ばれるのですか?

Go言語のクロージャは、関数の中で別の関数を定義して、その関数を返す仕組みだからです。外側の関数で定義した変数を、内側の関数が記憶するため「関数内関数」という表現がよく使われます。
関連セミナーのご案内

【超入門】ゼロから始めるGo言語プログラミング:最速で「動くアプリ」を作るマンツーマン指導

「プログラミングの仕組み」が根本からわかる。Go言語でバックエンド開発の第一歩を。

本講座を受講することで、単なる文法の暗記ではなく、「プログラムがコンピュータの中でどう動いているか」という本質的な理解につながります。シンプルながら強力なGo言語(Golang)を通じて、現代のバックエンドエンジニアに求められる基礎体力を最短距離で身につけます。

具体的な開発内容と環境

【つくるもの】
ターミナル(黒い画面)上で動作する「対話型計算プログラム」や、データを整理して表示する「ミニ・ツール」をゼロから作成します。自分の書いたコードが形になる感動を体験してください。

【開発環境】
プロの現場でシェアNo.1のVisual Studio Code (VS Code)を使用します。インストールから日本語化、Go言語用の拡張機能設定まで、現場基準の環境を一緒に構築します。

この60分で得られる3つの理解

1. 環境構築の完全な理解

「なぜ動くのか」という設定の仕組みを理解し、今後の独学で詰まらない土台を作ります。

2. Go言語の基本構造(変数・型)

データの種類やメモリの概念など、他言語にも通じるプログラミングの本質を学びます。

3. 読みやすいコードの書き方

ただ動くだけでなく、誰が見ても分かりやすい「綺麗なコード」を書くための考え方を伝授します。

※本講座は、将来的にバックエンドエンジニアクラウドインフラに興味がある未経験者のためのエントリー講座です。マンツーマン形式により、あなたの理解度に合わせて進行します。

セミナー画像

初めてのGo言語を一緒に学びましょう!

カテゴリの一覧へ
新着記事
New1
Go言語
Go言語のwhile的なforループの使い方!条件式ループの基本を解説
New2
Go言語
Go言語プログラムの実行方法まとめ!VSCode・ターミナルでの実行手順を解説
New3
Swift
Swift意味とは?プログラミング言語・金融・鳥の違いを徹底解説
New4
Swift
Swift 戻り値の扱い方と複数戻り値の返し方|初心者でも分かる関数の基本
人気記事
No.1
Java&Spring記事人気No1
Go言語
Go言語でリダイレクト処理を行う方法(http.Redirect)を初心者向けに解説
No.2
Java&Spring記事人気No2
Swift
Swift開発環境の構築方法を徹底解説!Xcode・Windows・Linux対応
No.3
Java&Spring記事人気No3
Kotlin
Android Studioのインストール手順と初期設定を初心者向けに完全解説!
No.4
Java&Spring記事人気No4
Kotlin
Gradleファイル(build.gradle.kts)の書き方と役割をやさしく解説!Kotlin初心者向け完全ガイド
No.5
Java&Spring記事人気No5
Go言語
Go言語のgo.modファイル完全ガイド!初心者でもわかる仕組みと書き方
No.6
Java&Spring記事人気No6
Swift
Swift Playgroundの使い方を完全解説!初心者に最適な学習環境の始め方
No.7
Java&Spring記事人気No7
Go言語
Go言語で条件式を1行で書くコツ!三項演算子の代替と短縮記法
No.8
Java&Spring記事人気No8
Kotlin
Kotlinの演算子一覧と使い方!算術・比較・論理演算子の基本を解説