Swift - Fermetures

Les fermetures dans Swift 4 sont similaires à celles des fonctions autonomes organisées en blocs et appelées n'importe où comme les langages C et Objective C. Les constantes et références de variables définies à l'intérieur des fonctions sont capturées et stockées dans des fermetures. Les fonctions sont considérées comme des cas particuliers de fermetures et prennent les trois formes suivantes -

Fonctions globales Fonctions imbriquées Expressions de fermeture
Avoir un nom. Ne saisissez aucune valeur Avoir un nom. Capturer les valeurs de la fonction englobante Les fermetures sans nom capturent les valeurs des blocs adjacents

Les expressions de fermeture en langage Swift 4 suivent des styles de syntaxe nets, optimisés et légers qui incluent.

  • Inférer des types de paramètres et de valeurs de retour à partir du contexte.
  • Retours implicites des fermetures d'expression unique.
  • Noms d'arguments abrégés et
  • Syntaxe de fermeture de fin

Syntaxe

Voici une syntaxe générique pour définir la fermeture qui accepte les paramètres et renvoie un type de données -

{
   (parameters) −> return type in
   statements
}

Voici un exemple simple -

let studname = { print("Welcome to Swift Closures") }
studname()

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

Welcome to Swift Closures

La fermeture suivante accepte deux paramètres et renvoie une valeur booléenne -

{     
   (Int, Int) −> Bool in
   Statement1
   Statement 2
   ---
   Statement n
}

Voici un exemple simple -

let divide = {
   (val1: Int, val2: Int) -> Int in 
   return val1 / val2 
}

let result = divide(200, 20)
print (result)

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

10

Expressions dans les fermetures

Les fonctions imbriquées offrent un moyen pratique de nommer et de définir des blocs de code. Au lieu de représenter la déclaration de fonction entière et les constructions de nom sont utilisées pour désigner des fonctions plus courtes. La représentation de la fonction dans une brève déclaration claire avec une syntaxe ciblée est obtenue grâce à des expressions de fermeture.

Programme d'ordre croissant

Le tri d'une chaîne est réalisé par la fonction réservée de clé Swift 4s "triée" qui est déjà disponible dans la bibliothèque standard. La fonction trie les chaînes données dans l'ordre croissant et renvoie les éléments dans un nouveau tableau avec la même taille et le même type de données que ceux mentionnés dans l'ancien tableau. L'ancien tableau reste le même.

Deux arguments sont représentés dans la fonction triée -

  • Valeurs de type connu représentées sous forme de tableaux.

  • Contenu du tableau (Int, Int) et renvoie une valeur booléenne (Bool) si le tableau est trié correctement, il renverra la valeur vraie sinon il retournera faux.

Une fonction normale avec une chaîne d'entrée est écrite et transmise à la fonction triée pour obtenir les chaînes triées dans le nouveau tableau qui est illustré ci-dessous -

func ascend(s1: String, s2: String) -> Bool {
   return s1 > s2
}

let stringcmp = ascend(s1: "Swift 4", s2: "great")
print (stringcmp)

Lorsque nous exécutons le programme ci-dessus en utilisant le terrain de jeu, nous obtenons le résultat suivant -

true

Le tableau initial à trier pour la glace est donné comme "Swift 4" et "grand". La fonction pour trier le tableau est déclarée comme type de données chaîne et son type de retour est mentionné comme booléen. Les deux chaînes sont comparées et triées par ordre croissant et stockées dans un nouveau tableau. Si le tri est effectué avec succès, la fonction retournera une valeur vraie, sinon elle retournera faux.

La syntaxe de l'expression de fermeture utilise -

  • paramètres constants,
  • paramètres variables, et
  • paramètres inout.

L'expression de fermeture ne prenait pas en charge les valeurs par défaut. Les paramètres variadiques et les tuples peuvent également être utilisés comme types de paramètres et types de retour.

let sum = {
   (no1: Int, no2: Int) -> Int in 
   return no1 + no2 
}

let digits = sum(10, 20)
print(digits)

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

30

Les paramètres et les déclarations de type de retour mentionnés dans l'instruction de fonction peuvent également être représentés par la fonction d'expression de fermeture en ligne avec le mot-clé 'in'. Une fois le paramètre et les types de retour déclarés, le mot clé «in» est utilisé pour désigner le corps de la fermeture.

Retours implicites d'expression unique

Ici, le type de fonction du deuxième argument de la fonction triée indique clairement qu'une valeur booléenne doit être renvoyée par la fermeture. Étant donné que le corps de la fermeture contient une seule expression (s1> s2) qui renvoie une valeur booléenne, il n'y a pas d'ambiguïté et le mot-clé return peut être omis.

Pour renvoyer une instruction d'expression unique dans les fermetures d'expression, le mot clé 'return' est omis dans sa partie déclaration.

var count:[Int] = [5, 10, -6, 75, 20]
let descending = count.sorted(by: { n1, n2 in n1 > n2 })
let ascending = count.sorted(by: { n1, n2 in n1 < n2 })

print(descending)
print(ascending)

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

[75, 20, 10, 5, -6]
[-6, 5, 10, 20, 75]

L'instruction elle-même définit clairement que lorsque string1 est supérieur à string 2 return true sinon false donc l'instruction return est omise ici.

Fermetures de type connu

Considérez l'ajout de deux nombres. Nous savons que l'addition renverra le type de données entier. Par conséquent, les fermetures de type connu sont déclarées comme -

let sub = {
   (no1: Int, no2: Int) -> Int in 
   return no1 - no2 
}

let digits = sub(10, 20)
print(digits)

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

-10

Déclaration de noms d'arguments abrégés comme fermetures

Swift 4 fournit automatiquement des noms d'arguments abrégés aux fermetures en ligne, qui peuvent être utilisés pour faire référence aux valeurs des arguments de la fermeture par les noms $ 0, $ 1, $ 2, etc.

var shorthand: (String, String) -> String
shorthand = { $1 }
print(shorthand("100", "200"))

Ici, $ 0 et $ 1 font référence aux premier et deuxième arguments String de la fermeture.

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

200

Swift 4 permet à l'utilisateur de représenter les fermetures en ligne sous forme de noms d'arguments abrégés en représentant $ 0, $ 1, $ 2 --- $ n.

La liste des arguments de fermeture est omise dans la section de définition lorsque nous représentons des noms d'argument abrégés dans des expressions de fermeture. En fonction du type de fonction, les noms des arguments abrégés seront dérivés. Étant donné que l'argument abrégé est défini dans le corps de l'expression, le mot clé «in» est omis.

Les fermetures en tant que fonctions d'opérateur

Swift 4 fournit un moyen facile d'accéder aux membres en fournissant simplement des fonctions d'opérateur comme des fermetures. Dans les exemples précédents, le mot-clé 'Bool' est utilisé pour renvoyer soit 'true' lorsque les chaînes sont égales, sinon il renvoie 'false'.

L'expression est rendue encore plus simple par la fonction d'opérateur en fermeture comme -

let numb = [98, -20, -30, 42, 18, 35]
var sortedNumbers = numb.sorted ({
   (left: Int, right: Int) -> Bool in
   return left < right
})

let asc = numb.sorted(<)
print(asc)

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

[-30, -20, 18, 35, 42, 98]

Fermetures en tant que remorques

Le passage de l'argument final de la fonction à une expression de fermeture est déclaré à l'aide de 'Trailing Closures'. Il est écrit en dehors de la fonction () avec {}. Son utilisation est nécessaire lorsqu'il n'est pas possible d'écrire la fonction en ligne sur une seule ligne.

reversed = sorted(names) { $0 > $1}

où {$ 0> $ 1} sont représentés comme des fermetures de fin déclarées à l'extérieur de (noms).

import Foundation
var letters = ["North", "East", "West", "South"]

let twoletters = letters.map({ 
   (state: String) -> String in
   return state.substringToIndex(advance(state.startIndex, 2)).uppercaseString
})

let stletters = letters.map() { 
   $0.substringToIndex(advance($0.startIndex, 2)).uppercaseString 
}
print(stletters)

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

[NO, EA, WE, SO]

Capture de valeurs et de types de référence

Dans Swift 4, la capture des constantes et des valeurs de variables se fait à l'aide de fermetures. Il fait en outre référence et modifie les valeurs de ces constantes et variables à l'intérieur du corps de fermeture même si les variables n'existent plus.

La capture des valeurs constantes et variables est obtenue en utilisant une fonction imbriquée en écrivant la fonction avec dans le corps d'une autre fonction.

Une fonction imbriquée capture -

  • Arguments de fonction externe.
  • Capturez les constantes et les variables définies dans la fonction externe.

Dans Swift 4, lorsqu'une constante ou une variable est déclarée à l'intérieur d'une fonction, les références à ces variables sont également créées automatiquement par la fermeture. Il offre également la possibilité de faire référence à plus de deux variables comme la même fermeture comme suit -

let decrem = calcDecrement(forDecrement: 18)
decrem()

Ici oneDecrement et les variables de décrémentation pointeront toutes les deux sur le même bloc de mémoire comme référence de fermeture.

func calcDecrement(forDecrement total: Int) -> () -> Int {
   var overallDecrement = 100
   func decrementer() -> Int {
      overallDecrement -= total
      print(overallDecrement)
      return overallDecrement
   }
   return decrementer
}

let decrem = calcDecrement(forDecrement: 18)
decrem()
decrem()
decrem()

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

82
64
46

Lorsque chaque fois que la fonction externe calcDecrement est appelée, elle appelle la fonction decrementer () et décrémente la valeur de 18 et retourne le résultat à l'aide de la fonction externe calcDecrement. Ici, calcDecrement agit comme une fermeture.

Même si la fonction décrémenter () n'a pas d'arguments, la fermeture par défaut se réfère aux variables 'globalDecrement' et 'total' en capturant ses valeurs existantes. La copie des valeurs des variables spécifiées est stockée avec la nouvelle fonction décrémenteur (). Swift 4 gère les fonctions de gestion de la mémoire en allouant et en libérant des espaces mémoire lorsque les variables ne sont pas utilisées.