カテゴリ: Go言語 更新日: 2026/02/13

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の値をクロージャが覚えているからです。

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

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

※ Amazon広告リンク

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言語のクロージャとは、関数の中で作られた関数が、外側の関数の変数を覚えて使い続ける仕組みのことです。普通の関数は呼び出すたびに初期化されますが、クロージャは前回の状態を残したまま処理を進められます。そのため、累積計算や状態管理が簡単にできる便利な機能です。
カテゴリの一覧へ
新着記事
New1
Go言語
Go言語の構造体の初期化パターンとコンストラクタ的関数の書き方を徹底解説!初心者でもわかる基本と実用例
New2
Kotlin
Kotlinの例外処理とキャンセルの連携を完全ガイド!初心者でもわかるCoroutineExceptionHandlerの使い方
New3
Go言語
Go言語のクロージャとは?関数内関数の活用例と仕組み
New4
Swift
Swiftでエラー原因を可視化!ログとトレースのベストプラクティスを初心者向けに解説
人気記事
No.1
Java&Spring記事人気No1
Kotlin
KotlinのChannelでデータをやり取りする方法を完全ガイド!初心者にもわかる非同期通信の基本
No.2
Java&Spring記事人気No2
Go言語
Go言語でのDB接続情報を環境変数で管理する方法|初心者でも安全に設定
No.3
Java&Spring記事人気No3
Kotlin
Kotlinのビルド設定エラーと解決法まとめ!初心者向けGradleトラブル対処ガイド
No.4
Java&Spring記事人気No4
Kotlin
Android Studioのインストール手順と初期設定を初心者向けに完全解説!
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
Swift
Swift Playgroundの使い方を完全解説!初心者に最適な学習環境の始め方
No.8
Java&Spring記事人気No8
Go言語
Go言語のgo.modファイル完全ガイド!初心者でもわかる仕組みと書き方

💻 作業効率アップに

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

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

※ Amazon広告リンク