Fermetures
Capturez l’état
Fermetures est une leçon Scala for Backend Engineering & Functional Programming gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Scala for Backend Engineering & Functional Programming, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Scala for Backend Engineering & Functional Programming comprend 4 leçons au total.
Qu’est-ce qu’une fermeture ?
Une fermeture est une fonction qui capture des variables dans la portée environnante où elle a été définie. Elle « capture » ces variables et conserve l’accès à celles-ci, même après la fin de cette portée.
object Main {
def main(args: Array[String]): Unit = {
val factor = 3
val multiply = (x: Int) => x * factor
println(multiply(5))
}
}Capturer une variable libre
Dans x => x * factor, x est un paramètre, tandis que factor est une variable libre provenant de la portée englobante. La fonction conserve une référence vers celle-ci.
object Main {
def main(args: Array[String]): Unit = {
val greeting = "Hello"
val greet = (name: String) => s"$greeting, $name!"
println(greet("Ann"))
println(greet("Bob"))
}
}Les fermetures survivent à leur portée
Lorsqu’une fonction renvoie une fermeture, les variables capturées restent accessibles aussi longtemps que la fermeture, même si la fonction qui l’a définie est déjà terminée.
object Main {
def makeAdder(n: Int): Int => Int = x => x + n
def main(args: Array[String]): Unit = {
val add10 = makeAdder(10)
val add100 = makeAdder(100)
println(add10(5))
println(add100(5))
}
}Chaque fermeture possède sa propre capture
Appeler deux fois une fabrique de fonctions produit deux fermetures indépendantes, chacune conservant sa propre valeur capturée.
object Main {
def prefixer(p: String): String => String = s => p + s
def main(args: Array[String]): Unit = {
val withDr = prefixer("Dr. ")
val withMr = prefixer("Mr. ")
println(withDr("Smith"))
println(withMr("Jones"))
}
}Capturer un état mutable
Une fermeture peut capturer un var, le lire et le mettre à jour. Cela permet à une fermeture de conserver un état entre les appels, comme un compteur.
object Main {
def main(args: Array[String]): Unit = {
var count = 0
val increment = () => { count += 1; count }
println(increment())
println(increment())
println(increment())
}
}Une fabrique de compteurs
Combinez ces idées : une fonction qui renvoie une fermeture capturant son propre var privé vous fournit un compteur encapsulé et indépendant.
object Main {
def counter(): () => Int = {
var n = 0
() => { n += 1; n }
}
def main(args: Array[String]): Unit = {
val c1 = counter()
val c2 = counter()
println(c1())
println(c1())
println(c2())
}
}Les fermetures capturent des références, pas des copies
Une fermeture capture la variable, et non un instantané. Si le var capturé est modifié après la création de la fermeture, celle-ci voit la nouvelle valeur.
object Main {
def main(args: Array[String]): Unit = {
var msg = "first"
val show = () => println(msg)
show()
msg = "second"
show()
}
}Privilégier la capture d’un val
Capturer un val immuable évite les surprises : la valeur capturée ne change jamais, et la fermeture se comporte donc de manière prévisible. Dans le code fonctionnel, privilégiez la capture de val.
object Main {
def main(args: Array[String]): Unit = {
val taxRate = 0.2
val withTax = (price: Double) => price * (1 + taxRate)
println(withTax(100))
}
}Fermetures et méthodes des collections
Les lambdas transmises à map, filter, etc. sont des fermetures dès qu’elles font référence à des variables externes. C’est extrêmement courant en Scala au quotidien.
object Main {
def main(args: Array[String]): Unit = {
val threshold = 3
val nums = List(1, 2, 3, 4, 5)
val big = nums.filter(_ > threshold)
println(big)
}
}Un piège de capture dans les boucles
En Scala, la variable d’une boucle for est une nouvelle liaison à chaque itération ; les fermetures capturent donc des valeurs distinctes. Cela évite un bogue classique présent dans certains autres langages.
object Main {
def main(args: Array[String]): Unit = {
val fns = for (i <- 1 to 3) yield () => i
println(fns.map(f => f()))
}
}Les fermetures encapsulent comportement et données
Une fermeture regroupe un comportement (le corps de la fonction) et des données (les variables capturées). C'est une alternative légère à un petit objet doté d'une seule méthode.
object Main {
def discounter(rate: Double): Double => Double = price => price * (1 - rate)
def main(args: Array[String]): Unit = {
val sale = discounter(0.25)
println(sale(80))
println(sale(200))
}
}Vérification rapide
Que capture une fermeture dans la portée qui l'entoure ?
Récapitulatif
Vous avez découvert les fermetures :
- Une fermeture capture les variables libres de sa portée englobante
- Les variables capturées vivent plus longtemps que la fonction qui les définit
- Chaque instance de fermeture possède son propre état capturé
- Les fermetures capturent des références, donc les captures mutables peuvent changer
- Les lambdas passées à
map/filtersont des fermetures utilisées au quotidien
Questions Fréquemment Posées
La leçon « Fermetures » est-elle gratuite ?
Oui — le texte complet de « Fermetures » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Scala for Backend Engineering & Functional Programming, passe à CoddyKit PRO. Le cours Scala for Backend Engineering & Functional Programming comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Fermetures » ?
Capturez l’état Tu pratiques Scala for Backend Engineering & Functional Programming avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Scala for Backend Engineering & Functional Programming ?
Aucune expérience préalable n'est requise. Scala for Backend Engineering & Functional Programming sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Fermetures » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Scala for Backend Engineering & Functional Programming ?
Oui. Chaque leçon Scala for Backend Engineering & Functional Programming inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.