web-dev-qa-db-fra.com

Go a-t-il des expressions lambda ou similaires?

Go prend-il en charge les expressions lambda ou similaires?

Je souhaite porter une bibliothèque d'un autre langage utilisant les expressions lambda (Ruby).

52
loyalflow

Voici un exemple , copié et collé avec soin:

package main

import fmt "fmt"

type Stringy func() string

func foo() string{
  return "Stringy function"
}

func takesAFunction(foo Stringy){
  fmt.Printf("takesAFunction: %v\n", foo())
}

func returnsAFunction()Stringy{
  return func()string{
    fmt.Printf("Inner stringy function\n");
    return "bar" // have to return a string to be stringy
  }
}

func main(){
  takesAFunction(foo);
  var f Stringy = returnsAFunction();
  f();
  var baz Stringy = func()string{
    return "anonymous stringy\n"
  };
  fmt.Printf(baz());
}
46
perreal

Les expressions Lambda sont également appelées littéraux de fonction. Go les soutient complètement.

Voir les spécifications de langue: http://golang.org/ref/spec#Function_literals

Voir un code-walk, avec des exemples et une description: http://golang.org/doc/codewalk/functions/

29
Tim Ford

Oui

En programmation informatique, une fonction anonyme ou une abstraction lambda (littéral de fonction) est une définition de fonction qui n'est pas liée à un identificateur, et Go supporte les fonctions anonymes , qui peuvent former des fermetures. Les fonctions anonymes sont utiles lorsque vous souhaitez définir une fonction en ligne sans avoir à le nommer.

    package main
    import "fmt"

    func intSeq() func() int {
        i := 0
        return func() int {
            i += 1
            return i
        }
    }


    func main() {
       nextInt := intSeq()
       fmt.Println(nextInt())
       fmt.Println(nextInt())
       fmt.Println(nextInt())
       newInts := intSeq()
       fmt.Println(newInts())
    }

function intSeq renvoie une autre fonction, que nous définissons de manière anonyme dans le corps d'intSeq. La fonction retournée se ferme sur la variable i pour former une fermeture .

Output
$ go run closures.go
1
2
3
1
6
dinesh kandpal

Le golang ne semble pas faire d’expressions lambda, mais vous pouvez utiliser une fonction anonyme littérale, j’ai écrit quelques exemples lorsque j’étudiais en comparant l’équivalent en JS.

aucun argument ne retourne la chaîne:

func() string {
    return "some String Value"
}
//Js similar: () => 'some String Value'

avec des arguments de chaîne et une chaîne de retour

func(arg string) string {
    return "some String" + arg
}
//Js similar: (arg) => "some String Value" + arg

pas d'argument et pas de retour (void)

func() {
   fmt.Println("Some String Value")
} 
//Js similar: () => {console.log("Some String Value")}

avec arguments et aucun retour (void)

func(arg string) {
    fmt.Println("Some String " + arg)
}
//Js: (arg) => {console.log("Some String Value" + arg)}
2
Notim_

Oui, mais c’est une expression lambda dans sa forme la plus complète, les fermetures et tout. Toutefois, vous n’obtenez pas d’inférence de type avec les littéraux de fonction!

0
Hoang Huu

Un exemple qui n’a pas encore été fourni et que je cherchais consiste à affecter directement des valeurs à variable/s à partir d’une fonction anonyme, par exemple.

test1, test2 := func() (string, string) {
    x := []string{"hello", "world"}
    return x[0], x[1]
}()

Remarque: vous avez besoin des crochets () à la fin de la fonction pour l'exécuter et renvoyer les valeurs, sinon seule la fonction est renvoyée et génère une erreur assignment mismatch: 2 variable but 1 values.

0
James Burke

Voici un exemple que je cherchais - comment passer directement une fonction anonyme à un rappel vers une autre fonction.

Supposons que nous ayons une fonction filter qui prend une valeur de type slice of int et un rappel qui sert de fonction de prédicat pour filtrer les valeurs (les valeurs qui passent le contrôle de prédicat sont renvoyées)

func filter(xi []int, predicate func(v int) bool) []int {
    filtered := []int{}

    for _, x := range xi {
        if predicate(x) {
            filtered = append(filtered, x)
        }
    }

    return filtered
}

Maintenant, si nous avons une tranche d’ints [1, 2, 3, 4] et que nous voulons obtenir une valeur paire, nous pouvons définir la fonction isEven au préalable avec la signature func isEven(x int) bool et lui transmettre le second argument de la fonction filter fonction mais nous pouvons également intégrer cette fonction de cette manière

even := filter(xi, func(x int) bool { return x%2 == 0 })

Notez que nous devons toujours spécifier les types d'arguments de la fonction ainsi que les types de valeurs renvoyées.

Juste pour référence, la ligne de code ci-dessus est équivalente à

func isEven(x int) bool {
    return x%2 == 0
}

even := filter(xi, isEven)
0
Matus Dubrava

Oui, car il s’agit d’un langage entièrement fonctionnel, mais n’a pas de grosse flèche (=>) ni de fine flèche (->) comme le signe lambda habituel, et utilise le mot clé func par souci de clarté et de simplicité. 

0
LEMUEL ADANE