web-dev-qa-db-fra.com

Fonctions de retour de Golang

Quelqu'un peut-il expliquer pourquoi les 0 et les 1 sont imprimés et rien d'autre? Je vous remercie!

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()
}

Quelqu'un peut-il expliquer pourquoi les 0 et les 1 sont imprimés et rien d'autre? Je vous remercie!

8
kunrazor

Regardons votre main:

Ligne 1

f := makeFunction("hellooo")
  • Effet secondaire: impression "00000"
  • Valeur renvoyée: une fonction anonyme qui exécute makeFunction2("abcef"), affectée à l'identifiant f

Ligne 2

f()

ce qui équivaut à:

_ = f()
  • Effet secondaire: impression "11111"
  • Valeur de retour: une fonction anonyme qui exécute makeFunction3("safsf"), ignorée (vous n'affectez pas la valeur de retour de f()).

makeFunction3 N'est jamais affecté à aucun identifiant et n'est jamais appelé.

5
Pierre Prinetti

Suivons le déroulement du programme:

  1. main démarre.
  2. main appelle makeFunction.
  3. makeFunction imprime 00000, et renvoie une fonction anonyme.
  4. De retour dans main, nous appelons la fonction anonyme retournée par l'appel précédent.
  5. La fonction anonyme appelle makeFunction2.
  6. makeFunction2 imprime 11111, et renvoie une fonction anonyme.
  7. main renvoie.

Étant donné que la valeur de retour est ignorée après l'étape 6 ci-dessus, rien d'autre n'est imprimé.

9
Adrian

Pour imprimer les 3, vous devez appeler deux fois:

f()()

Et pour imprimer les 4 aussi, faites simplement:

f()()()

Car ...

// 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()

Question test, qu'est-ce que cela imprime si vous faites cela?

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

C'est ce que l'on appelle le curry ou la fermeture, mais dans votre exemple, vous n'avez clôturé aucune valeur locale, donc cette dernière perd son sens.

2
Pie 'Oh' Pah

makeFunction renvoie uniquement la fonction makeFunction2. car ce n'est pas une fonction récursive. Si vous vous attendez à se comporter comme une fonction récursive, vous devez remplacer return func () {} par (return makeFunction2 ou 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