Swift : Class ou Struct ?

Dans quelles conditions mieux vaut-il employer une structure au détriment de nos chères classes ?

La différence entre les deux ?
Les classes et les structures on un petit paquet de choses en commun, comme la possibilité de définir et stocker des valeurs et des méthodes, de définir un initializer, et (un point vachement cool,) d’implementer des protocols définis.
La classe peut, en plus de la structure, jouer sur le concept phare du paradigme Orienté Objet, l’héritage.
Evidement, ce n’est pas tout, mais je ne vais pas m’y attarder plus longtemps.

Et l’implémentations ?
Assez similaire, voyez vous-même.

class SomeClass {
// some values, variables, constants or functions
var aNumber:Int!
}
struct SomeStructure {
// some values, variables, constants or functions
var aNumber:Int!
}

Pourquoi faire la difference ?
Quelques lignes de code valent mieux que 1000 mots (Non ? ^^)

let aClassInstance = SomeClass()
aClassInstance.aNumber = 5
let anotherClassInstance = aClassInstance
aClassInstance.aNumber = 10
var aStructInstance = SomeStructure()
aStructInstance.aNumber = 2
var anotherStructInstance = aStructInstance
aStructInstance.aNumber = 4

La première ligne crée une instance de SomeClass dans la mémoire, et met une référence de cette instance dans la constante aClassInstance.
La propriété membre variable SomeClass, aNumber, est modifiée sur cette instance : 5.
À la 3e ligne, je place une référence de ce même objet dans dans anotherClassInstance.
Je rechange, ensuite, la valeur de aNumber de aClassInstance qui passe ainsi de 5 à 10.

Je fais exactement la même chose avec une structure. J’en crée une instance (le terme s’applique aussi), je modifie la valeur d’un membre, et je crée une copie de cette instance avant de remodifier la même valeur.

Si, à la suite de ce code, je place des prints pour verifier les valeurs, voici ce que j’ai :

print(anotherClassInstance.aNumber)       //  10
print(anotherStructInstance.aNumber) // 2

Ce que ça veut dire … 
Quand on parle de Classe, on parle d’instance de classe, et de référence.
La copie d’un objet est une copie de sa référence, changer la valeur de l’objet revient à accéder à l’objet référencé et changer sa valeur.
Ce qui explique que, bien que anotherClassInstance n’ai pas été modifié, son membre aNumber l’ait été. anotherClassInstance pointe sur la même référence que aClassInstance.
Concernant la Structure, chaque variable contient une instance fixe, une nouvelle valeur, à son assignation.
Ainsi, anotherStructInstance n’écope pas des modifications de aStructInstance, il ne pointe pas dessus, ce sont deux instances qui sont différentes.

D’ailleurs, une chose remarquable sur les instances d’une structure est qu’il est impossible d’utiliser l’opérateur logique “==” sur deux instances d’une structure.
Il est possible cependant de contourner cela avec une redéfinition de l’opérateur logique.

func == (left:SomeStructure, right:SomeStructure) -> Bool {
// ...
}
TL;DR
Class = Référence
Structure = Valeur

Maintenant que nous sachons tout ça, quand utiliser l’un ou l’autre ?
On y vient.

Les Structures nous permettent de ne pas craindre quoi que ce soit en terme de fuites mémoire, ou de problèmes liés à d’éventuels threads en course qui voudraient accéder ou modifier une valeur d’une instance.
J’aurai donc tendance à dire que la structure est plus safe.

Les classes ne peuvent hériter que d’une seule classe mère (Orienté Objets). Les structures peuvent implémenter une infinité de protocols (Orienté Protocol).

La structure peut être optée dans les cas :
- De schémas de données simples et légers
- De concurrence de threads sur des opérations qui visent une même instance
- Où il n’est pas nécessaire de comparer et copier des instances.


Si l’on en croit la documentation d’Apple, il vaudrait mieux, par défaut, utiliser une classe et dans certains cas spécifiques opter pour la structure.

J’aurai tendance à dire le contraire.

La structure offre un schéma plus simple, plus safe et plus complet. Elle est le pilier de la programmation orientée protocole, le gros apport, à mon sens, du Swift.