Quantcast
Channel: Publicis Sapient Engineering – Engineering Done Right
Viewing all articles
Browse latest Browse all 1865

Pépite #18 – Types Existentiels en Swift

$
0
0

***Cette pépite est la première d’une série de trois. Elles forment la base de la classroom « From Existential to Opaque return types » qui s’est tenue lors de la FrenchKit 2019***

Pendant la dernière WWDC, Apple a annoncé des choses intéressantes, notamment ‘opaque return types’ et SwiftUI. Ce dernier utilise les pouvoirs du premier pour fournir aux développeurs des super pouvoirs.
Dans la proposition de ‘opaque return types’ vous pourrez trouver de multiples références à un document intitulé “Improving the UI of generics”, document écrit par Joe Groff dans lequel il décrit l’état actuel et le futur des génériques en Swift. C’est dans cet article que je me suis retrouvé face ce terme: Type Existentiel.

  • Qu’est qu’un type existentiel ?

La définition la plus simple que l’on pourrait donner d’un type existentiel est la suivante: un type qui existe et satisfait certaines contraintes.
Cette définition semble très proche de celle d’un protocole comme type et cela à juste titre parce que la façon la plus simple de créer un type existentiel est justement l’utilisation d’un protocole en tant que contrainte.

Plus concrètement:

protocol CustomStringConvertible {

    var description: String { get set }

}

let myVariable: CustomStringConvertible

et Voila ! myVariable de type CustomStringConvertible a maintenant un type existentiel.
C’est-à-dire, myVariable a un type qui existe et satisfait les contraintes définies par le protocole. On ne le connait pas pour l’instant. Celui-ci pourrait bien être Float, String ou un autre type qui est conforme au protocole.

En coulisses, il existe une ‘boite’, qui est appelée conteneur existentiel, qui contient la valeur qui conforme au protocole, une référence à sa Value Witness Table et une référence à sa Protocol Witness Table (Concepts qui sont hors périmètre de cet article ). Cette boite a une taille fixe pour pouvoir stocker aussi bien une instance de type valeur qu’un type référence et c’est justement cette taille fixe qui nous permet de les utiliser par exemple dans un array ou de les utiliser de façon interchangeable.

Cela me permet par exemple d’écrire du code comme ceci:

var variables: [CustomStringConvertible] = []

Class MyClass: CustomStringConvertible {
    var description: String = "This is my class"
}

Class OtherClass: CustomStringConvertible {
    var description: String = "This is another class"
}

variables.append(MyClass(), OtherClass())

Ce qui nous permet d’ajouter dans un même tableau 2 instances de 2 classes différentes.

  • Les limitations du type existentiel en Swift

Les existentiels dans Swift ont quelques limitations comme par exemple:

– l’impossibilité de définir une valeur de type protocole quand celui-ci a un associated type ou utilise Self comme contrainte

l’impossibilité de définir une valeur de type protocole et de contraindre cette valeur à avoir un associated type défini.

  • D’autres existentiels en Swift ?

Il existe d’autres existentiels en Swift comme Any, AnyObject et AnyClass
Ces types cachent ou effacent le type d’une valeur enveloppée à laquelle ils transfèrent des opération, par exemple des comparaisons d’égalité.
Ces types utilisent une méthode appelée Type-Erasure que l’on approfondira dans une prochaine pépite.


Viewing all articles
Browse latest Browse all 1865

Trending Articles