Créer une fonction anonyme permet de définir une fonction dans le corps d'une autre fonction (on parle d'inline) sans avoir à la nommer. Voici un exemple qui n'a pas vraiment d'application directe, mais qui permet d'illustrer le propos (le programme affichera "salut") en avançant étape par étape :
On peut utiliser ce mécanisme pour créer une clôture (en anglais, closure). D'après Wikipédia, une closure est créée lorsqu'une fonction est définie dans le corps d'une autre fonction et fait référence à des arguments ou des variables locales à la fonction dans laquelle elle est définie. Voici un exemple de code illustrant ce concept :
Ce code retournera le résultat suivant, ce qui montre que l'état de chacune des deux instances de la fonction compteur est unique :
1 2 3 101 102
Certaines fonctions, par exemple celle qui définit le routage d'une application web, n'acceptent en paramètre une fonction n'ayant que x paramètres :
func main() { http.HandleFunc("/home", homeHandler) http.ListenAndServe(":9999", nil) } func homeHandler(w http.ResponseWriter, r *http.Request) { p := Page{Titre: "mon premier essai"} err := templates.ExecuteTemplate(w, "index.html", p) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } }
Imaginons maintenant que vous souhaitiez initialiser ce contrôleur avec un paramètre supplémentaire. Si vous vous contentez d'ajouter un paramètre dans son prototype, le compilateur retournera une erreur parce que la fonction HandleFunc n'accepte pour paramètre qu'une fonction ayant deux paramètres. L'utilisation d'une fonction anonyme permet de vous sortir de ce mauvais pas. Voici un exemple de code complet :
package main import ( "net/http" "html/template" ) type Page struct { Titre string } var templates = template.Must(template.ParseFiles("index.html")) func main() { valeurInit := "mon premier essai" http.HandleFunc("/home", func(w http.ResponseWriter, r *http.Request) { homeHandler(w, r, valeurInit) }) http.ListenAndServe(":9999", nil) } func homeHandler(w http.ResponseWriter, r *http.Request, titre string) { p := Page{Titre: titre} err := templates.ExecuteTemplate(w, "index.html", p) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } }
Comment déclencher une fonction de manière périodique ou différée ? Voyons comment faire avec la bibliothèque standard. Lire »
Exemples d'utilisation du type chan et des go routines stateful et stateless Lire »
Préconisations officielles pour la gestion des erreurs dans un programme golang. Cet article complète les explications sur panic, defer et recover Lire »
Une traduction du blog officiel de golang expliquant le mécanisme de la réflexion en Go. Lire »
Cet article vous permettra de comprendre une des bases de tous les langages de programmation : Types, Valeurs, Variables et constantes en go Lire »
Soyez le premier à commenter cet article
Tous les commentaires sont soumis à modération. Les balises HTML sont pour la plupart autorisées. Les liens contextuels et intéressants sont en follow.