web-dev-qa-db-ja.com

Golangの戻り関数

なぜ0と1が印刷され、他に何も印刷されないのか、誰か説明できますか?ありがとうございました!

func makeFunction(name string) func() {
    fmt.Println("00000")
    return func() {
        makeFunction2("abcef")
    }
}

func makeFunction2(name string) func() {
    fmt.Println("11111")
    return func() {
        makeFunction3("safsf")
    }
}

func makeFunction3(name string) func() {
    fmt.Println("33333")
    return func() {
        fmt.Printf("444444")
    }
}

func main() {
    f := makeFunction("hellooo")
    f()
}

なぜ0と1が印刷され、他に何も印刷されないのか、誰か説明できますか?ありがとうございました!

8
kunrazor

mainを見てみましょう:

ライン1

_f := makeFunction("hellooo")
_
  • 副作用:「00000」の印刷
  • 戻り値:識別子fに割り当てられたmakeFunction2("abcef")を実行する無名関数

2行目

_f()
_

これは次と同等です:

__ = f()
_
  • 副作用:「11111」の印刷
  • 戻り値:makeFunction3("safsf")を実行する匿名関数が破棄されました(f()の戻り値は割り当てていません)。

_makeFunction3_が識別子に割り当てられることはなく、呼び出されることもありません。

5
Pierre Prinetti

プログラムの流れに従ってみましょう:

  1. mainが始まります。
  2. mainmakeFunctionを呼び出します。
  3. makeFunction00000を出力し、無名関数を返します。
  4. mainに戻り、前の呼び出しで返された無名関数を呼び出します。
  5. 無名関数はmakeFunction2を呼び出します。
  6. makeFunction211111を出力し、無名関数を返します。
  7. mainが返されます。

上記のステップ6の後で戻り値は破棄されるため、何も出力されません。

9
Adrian

3を出力するには、2回呼び出す必要があります。

f()()

4も印刷するには、次のようにします。

f()()()

なぜなら...

// prints "00000" and returns a function that if run
// will invoked `makeFunction2`
f := makeFunction("hello")

// `makeFunction2` is called, printing "11111" and returns 
// a function that if run will invoked `makeFunction3`
f1 := f()

// `makeFunction3` is called, printing "33333" and returns
// a function that if run will invoked `makeFunction4`
f2 := f1()

テスト問題、これを行うと何が出力されますか?

f := makeFunction("Hello")()()
f()

これはカリー化またはクロージャーとして知られていますが、例ではローカル値をクローズしていないため、後者は意味を失っています。

2
Pie 'Oh' Pah

makeFunctionは、関数makeFunction2のみを返します。これは再帰的な関数ではないためです。再帰関数のように動作することが予想される場合は、return func(){}を(return makeFunction2または3)に変更する必要があります

func makeFunction(name string) func() {
    fmt.Println("00000")
    return makeFunction2("abcef")
}

func makeFunction2(name string) func() {
    fmt.Println("11111")
    return makeFunction3("safsf")
}

func makeFunction3(name string) func() {
    fmt.Println("33333")
    return func() {
        fmt.Printf("444444")
    }
}

func main() {
    f := makeFunction("hellooo")
    f()
}

// Output: 
00000
11111
33333
444444
0
yoell32