ホームページ > バックエンド開発 > Golang > golangにおけるクロージャの意味と使い方をご存知ですか?

golangにおけるクロージャの意味と使い方をご存知ですか?

藏色散人
リリース: 2020-12-24 15:25:42
転載
2449 人が閲覧しました

次のコラム golang チュートリアル では、golang におけるクロージャの意味と使い方を紹介します。困っている友人の役に立てば幸いです。

golangにおけるクロージャの意味と使い方をご存知ですか?

#クロージャとは何ですか?

Go 関数はクロージャになることができます。クロージャは、関数本体の外側の変数を参照する関数値です。この関数は、参照された変数にアクセスして値を割り当てることができます。つまり、関数は変数に「バインド」されています。

私の不確かな理解ですが、

クロージャはクラスのインスタンスに相当し、関数本体の外にある変数はこのインスタンスに格納されている変数に相当します。

クロージャがない場合、関数は 1 回限りのトランザクションです。関数の実行後、関数内の変数の値は変更できません (メモリを解放する必要があります)。クロージャが終了すると、関数は変数の値になります。変数が解放されない限り、関数は常に有効で排他的です。そのため、関数内の変数の値は後で変更できます(この方法ではメモリがgo によって再利用されることはなく、常に There にキャッシュされます)。

クロージャの主な重要性

変数のスコープを縮小し、グローバル変数の汚染を軽減します。次のような蓄積をグローバル変数を使用して実装すると、グローバル変数は他の変数によって簡単に汚染されてしまいます。同時に、n 個のアキュムレータを実装したい場合は、毎回 n 個のグローバル変数が必要になります。バックパックを使用すると、生成された各アキュムレータ

myAdder1, myAdder2 := adder(), adder() は独自の独立した合計を持ち、合計は myAdder1.sum および myAdder2.sum と見なすことができます。

バックパックを使用して、独自の状態を持つ

関数を実装できます!

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

package mainimport (

    "fmt")func adder() func(int) int {

    sum := 0

    return func(x int) int {

        sum += x      return sum }}func main() {

    myAdder := adder()

     

    // 从1加到10

    for i := 1; i <= 10; i++ {

        myAdder(i)

    }

     

    fmt.Println(myAdder(0))

    // 再加上45

    fmt.Println(myAdder(45))}

ログイン後にコピー
結果:


1

2

55      // 1+...+10

100

ログイン後にコピー

クロージャを使用してフィボナッチ数列を実装する

1

2

3

4

5

6

7

8

9

10

11

12

package mainimport (

    "fmt")func fibonacci() func() int {

    b0 := 0

    b1 := 1

    return func() int {

        tmp := b0 + b1

        b0 = b1

        b1 = tmp      return b1  }}func main() {

    myFibonacci := fibonacci()

    for i := 1; i <= 5; i++ {

        fmt.Println(myFibonacci())

    }}

ログイン後にコピー
結果:


1

2

3

4

5

1

2

3

5

8

ログイン後にコピー

誤りやすい点

1

2

3

4

5

6

7

8

9

10

11

12

func B() []func() {

    b := make([]func(), 3, 3)

    for i := 0; i < 3; i++ {

        b[i] = func() {

            fmt.Println(i)

        }

    }

    return b}func main() {

    c := B()

    c[0]()

    c[1]()

    c[2]()}

ログイン後にコピー
結果:


1

2

3

4

// 因为都引用i,i最后变成了3

3

3

3

ログイン後にコピー
修正方法1:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

package mainimport (

    "fmt")func B() []func() {

    b := make([]func(), 3, 3)

    for i := 0; i < 3; i++ {

        j := i

        b[i] = func() {

            fmt.Println(j)

        }

    }

    return b}func main() {

    c := B()

    c[0]()

    c[1]()

    c[2]()}

ログイン後にコピー
修正方法 2:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

package mainimport (

    "fmt")func B() []func() {

    b := make([]func(), 3, 3)

    for i := 0; i < 3; i++ {

        b[i] = func(j int) func(){

            return func() {

                fmt.Println(j)

            }

        }(i)

    }

    return b}func main() {

    c := B()

    c[0]()

    c[1]()

    c[2]()}

ログイン後にコピー
その他の関連技術記事については、

go language チュートリアル列をご覧ください。

以上がgolangにおけるクロージャの意味と使い方をご存知ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート