Go言語(golang)のクロージャ(closure)

※当サイトではアフィリエイト広告を利用しています

目次

Go言語(golang)のクロージャ(closure)

クロージャの使い方を説明します。Tour of Goを参考にしています。

Go言語(golang)のクロージャ(closure)の使い方

Go言語のクロージャ(closure)は、関数とその関数が定義された環境(変数などのコンテキスト)を包括的に保持するものです。クロージャは、関数内で定義された関数で、外部の変数を参照できます。以下に、クロージャの基本的な例を示します。

package main

import "fmt"

func main() {
	// クロージャを定義して変数に代入
	add := func(x, y int) int {
		return x + y
	}

	// クロージャの使用
	result := add(3, 4)
	fmt.Println("Result:", result)
}

この例では、addという名前の変数にクロージャを代入しています。このクロージャは、引数 xy を受け取り、それらの値を加算して返す関数です。

クロージャは、外部の変数にアクセスすることができます。例えば、以下の例では、クロージャが外部の変数 counter にアクセスして、その値を保持しています。

package main

import "fmt"

func main() {
	// クロージャで外部変数にアクセス
	counter := 0
	increment := func() int {
		counter++
		return counter
	}

	// クロージャの使用
	fmt.Println(increment()) // 1
	fmt.Println(increment()) // 2
}

この例では、increment クロージャは counter 変数にアクセスして、その値を1ずつ増やしています。クロージャは外部変数をキャプチャすることで、その変数の状態を保持し続けることができます。

クロージャは無名関数としても使われることがあり、関数を変数に代入して扱ったり、関数の引数として渡したりする場面で役立ちます。

Go言語(golang)のクロージャ(closure)の注意点

変数のキャプチャ

クロージャは外部の変数をキャプチャします。そのため、クロージャ内で変数が変更されると、同じ変数を参照する他のクロージャやコードにも影響が及びます。

ループ変数の注意

クロージャ内でループ変数を使用すると、期待通りに動作しない可能性があります。ループ変数はイテレーションごとに新しい変数が作成されるため、クロージャ内でそれを参照すると最終的な値が予測できなくなります。この問題を解決するためには、ループ変数をループ内で明示的に引数として渡す必要があります。

package main

import "fmt"

func main() {
    var funcs []func()

    for i := 0; i < 3; i++ {
        // クロージャがループ変数をキャプチャする例(誤った使い方)
        funcs = append(funcs, func() {
            fmt.Println(i)
        })
    }

    for _, f := range funcs {
        f() // すべてのクロージャが最終的な i の値を表示
    }
}

結果

3
3
3

上記の例では、すべてのクロージャが同じ i の値を参照してしまいます。正しい方法はループ変数を引数として渡すことです。

package main

import "fmt"

func main() {
    var funcs []func()

    for i := 0; i < 3; i++ {
        // クロージャが正しくループ変数をキャプチャする例
        funcWithArg := func(x int) func() {
            return func() {
                fmt.Println(x)
            }
        }(i)

        funcs = append(funcs, funcWithArg)
    }

    for _, f := range funcs {
        f() // それぞれのクロージャが期待通りの値を表示
    }
}

結果

0
1
2
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

テック企業でプレイングマネージャーをしている Jun です。プログラミングの基礎をはじめ、組織やマネジメントについてブログを書いています。ハードスキル、ソフトスキルどちらも磨きたい方を対象にしています。一緒に学んで人生を楽しくしていきましょう!

目次