Programmation fonctionnelle en Go : possibilités et exemples

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Programmation fonctionnelle en Go : de la théorie à la pratique



Go (Golang) n'a pas été conçu à l'origine comme un langage purement fonctionnel. Cependant, son puissant système de types, la prise en charge des fonctions de première classe et des fermetures (closures) permettent d'appliquer avec succès les principes de la programmation fonctionnelle (FP). Dans cet article, nous allons voir comment utiliser le style fonctionnel en Go pour écrire un code plus prévisible, testable et thread-safe.



1. Fonctions de première classe et fonctions d'ordre supérieur



En Go, les fonctions sont des objets de première classe. Cela signifie qu'elles peuvent être assignées à des variables, passées comme arguments et retournées depuis d'autres fonctions. Les fonctions qui travaillent avec d'autres fonctions sont appelées fonctions d'ordre supérieur.



Exemple : passage d'une fonction comme argument



package main

import "fmt"

// Fonction d'ordre supérieur : prend une fonction et l'applique à un nombrefunc applyOperation(x int, op func(int) int) int { return op(x)}

func double(x int) int { return x * 2}

func square(x int) int { return x * x}

func main() { result1 := applyOperation(5, double) result2 := applyOperation(5, square)

fmt.Println("Double:", result1) // 10 fmt.Println("Square:", result2) // 25}


Exemple : retour d'une fonction depuis une fonction (fabrique de fonctions)



package main

import "fmt"

// Retourne une fonction qui ajoute une valeur donnéefunc createAdder(x int) func(int) int { return func(y int) int { return x + y }}

func main() { addFive := createAdder(5) addTen := createAdder(10)

fmt.Println(addFive(3)) // 8 fmt.Println(addTen(3)) // 13}


2. Fermetures (Closures) en Go



Une fermeture est une fonction qui "se souvient" des variables de la portée externe, même après que cette portée a terminé son exécution. Les fermetures sont un outil puissant pour créer un état encapsulé et des fabriques de fonctions.



Exemple : générateur de séquence



package main

import "fmt"

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

func main() { next := sequenceGenerator()

fmt.Println(next()) // 1 fmt.Println(next()) // 2 fmt.Println(next()) // 3

// Nouveau générateur commence à 1 next2 := sequenceGenerator() fmt.Println(next2()) // 1}


Important : Soyez prudent avec les fermetures dans les boucles. Dans les anciennes versions de Go (avant la 1.22), la variable i dans la boucle était réutilisée, ce qui entraînait des erreurs. À partir de Go 1.22, les variables de boucle sont capturées par valeur.



3. Fonctions pures et immuabilité



Une fonction pure est une fonction qui :

  • Retourne toujours le même résultat pour les mêmes arguments.
  • N'a pas d'effets secondaires (ne modifie pas l'état externe, n'écrit pas dans des fichiers/le réseau).

Go n'a pas de support intégré pour l'immuabilité, mais nous pouvons suivre ce principe par nous-mêmes.



Exemple : fonction pure vs fonction impure



package main

import "fmt"

// Fonction IMPURE : modifie la slice externevar counter int

func impureAddToSlice(s []int, val int) []int { counter++ // effet secondaire return append(s, val)}

// Fonction PURE : crée une nouvelle slicefunc pureAddToSlice(s []int, val int) []int { newSlice := make([]int, len(s)+1) copy(newSlice, s) newSlice[len(s)] = val return newSlice}

func main() { original := []int{1, 2, 3}

// Approche pure result := pureAddToSlice(original, 4) fmt.Println("Original:", original) // [1 2 3] - n'a pas changé fmt.Println("Result:", result) // [1 2 3 4]}


Conseil : Pour travailler avec des structures immuables

Blogs

Book Recommendations