Dans les langages de programmation, une closure est un concept puissant qui permet à une fonction de capturer et de conserver les références à des variables de son environnement lexical (l'environnement dans lequel la fonction est définie).
Cela signifie que même après que la fonction externe a fini de s'exécuter ou qu'elle est sortie de la portée, la fonction interne (la closure) conserve toujours l'accès aux variables de sa portée englobante. Les closures sont créées lorsqu'une fonction interne fait référence à des variables à partir de sa fonction contenante ou toute autre portée environnante. La fonction interne se ferme sur ces variables, d'où le terme closure.
La capacité d'une closure à maintenir l'accès aux variables de son environnement lexical est particulièrement utile dans les scénarios où vous devez créer des fonctions dont le comportement dépend des valeurs de certaines variables au moment de la définition de la fonction.
Voici un exemple simple de closure dans Power Query M :
let
x = 10,
closureFunction = () => x * 2
in
closureFunction()
Cette requête génère la valeur 20. Dans cet exemple, la variable x est définie dans le bloc let et a la valeur 10 (portée globale de la requête). closureFunction est une closure car elle capture la référence à la variable x à partir de son environnement lexical (actuel). Lorsque closureFunction est appelée plus tard dans la requête, elle a toujours accès à la valeur de x (10), et elle renverra le résultat de x * 2, soit 20.
Considérons maintenant un exemple plus complexe de closure dans Power Query M. Considérez la requête suivante :
let
x = 10,
closureFunction = () => x * 2,
Evaluation =
Expression.Evaluate(
"closureFunction()",
[
closureFunction = closureFunction,
x = 20
]
)
in
Evaluation
Compte tenu de notre explication de la portée et de la priorité de la portée locale, vous pouvez vous attendre à ce que cette requête renvoie 40 (20 * 2). Cependant, ce n'est pas le cas. Cette expression renvoie en fait 20 (10 * 2). L'explication est la closure.
Observez que closureFunction est défini à l'origine dans la portée où x est égal à 10. Tout comme dans l’exemple original, closureFunction capture toujours la référence à la variable x à partir de son environnement lexical original (actuel). Ainsi, cette clôture de la capture des valeurs actuelles dans le contexte de l'endroit où la fonction est définie à l'origine a la priorité sur le passage d'une valeur différente pour x (20) dans l'environnement de notre expression Expression.Evaluate, où nous appelons closureFunction.
En d'autres termes, la valeur de x de la portée de l'endroit où la fonction a été définie à l'origine est "désactivé” et ne peut pas être modifié.
Poussons ce concept de contexte original un peu plus loin. Considérez la question suivante :
let
multiplyFunction = ( x ) as function =>
( multiplier ) => x * multiplier,
closureFunction = multiplyFunction( 10 )
in
closureFunction( 2 )
Cette requête renvoie également 20. À première vue, il peut sembler que le code génère une erreur, car il n'y a apparemment jamais de moment où les expressions x et multiplier sont dans la même portée. Le secret réside dans la création d'une fonction qui renvoie une fonction et l'application de la closure.
La fonction multiplyFunction accepte un seul paramètre, x, et renvoie une fonction qui accepte un seul paramètre, le multiplicateur. Nous définissons closureFunction comme la fonction qui est renvoyée lors de l'appel de multiplyFunction avec une valeur de 10.
La closure entre en jeu ici parce que closureFunction se souvient de son contexte de définition d'origine où x est défini à 10 en invoquant multiplyFunction avec un argument de 10. Ainsi, la définition de la fonction renvoyée par multiplyFunction est fermée et définie comme une fonction où x est égal à 10.
Par conséquent, lorsque nous invoquons ultérieurement closureFunction avec une valeur de 2, le paramètre passé est le paramètre multiplicateur de la fonction renvoyée par l'appel de multiplyFunction avec une valeur de 10, et donc 10 * 2 = 20.
Les fermetures sont bénéfiques pour créer des fonctions réutilisables avec un comportement dynamique. Ils vous permettent de définir des fonctions qui dépendent de valeurs en dehors du corps de la fonction, ce qui vous donne plus de flexibilité et d'adaptabilité dans votre code Power Query M. Les closures sont souvent utilisées dans des scénarios avancés où vous devez créer des fonctions avec un comportement spécialisé basé sur un contexte ou des conditions spécifiques.
En termes d'utilisation pratique, les closures sont particulièrement pratiques à comprendre lorsqu'il s'agit de fonctions de transformation. De plus, les fermetures sont fondamentalement nécessaires à la mise en œuvre du pliage des requêtes (Querty folding).
Want to print your doc? This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (