Struct ou Class ? La question éternelle du développeur Swift
Quiconque commence à programmer en Swift se pose tôt ou tard cette question. Apparemment, les deux constructions permettent de créer des objets avec des données et des méthodes. Mais pourquoi cette question cumule-t-elle des milliers de vues sur Stack Overflow, et pourquoi les développeurs expérimentés privilégient-ils de plus en plus les structures ?
La réponse est simple : parce que le choix entre struct et class affecte directement les performances, la sécurité des threads et l'architecture de votre application. Dans cet article, nous aborderons non seulement la théorie, mais aussi des exemples concrets et des scénarios où Struct l'emporte clairement sur Class.
Si vous programmez en Swift et utilisez encore les classes « par habitude » d'Objective-C — cet article est pour vous. Préparez-vous à repenser vos approches.
La différence principale : Value Type vs Reference Type
Avant d'entrer dans les détails, rappelons la différence fondamentale :
- Struct est un value type (type valeur). Lors de l'affectation ou du passage à une fonction, une copie des données est créée.
- Class est un reference type (type référence). Lors de l'affectation ou du passage à une fonction, une référence au même objet en mémoire est transmise.
Cela semble anodin. Mais de cette différence « atomique » découlent toutes les conséquences que nous allons maintenant analyser.
Exemple 1 : Comportement inattendu de Class
class PersonClass { var name: String init(name: String) { self.name = name }}
struct PersonStruct { var name: String}
// Test de la classelet person1 = PersonClass(name: "Anna")let person2 = person1person2.name = "Marie"
print(person1.name) // Marie ! Changé aussi pour person1print(person2.name) // MarieVous avez remarqué le problème ? En changeant le nom de person2, nous avons involontairement modifié celui de person1. C'est le même objet en mémoire. Dans un petit exemple, ce n'est pas critique, mais dans un projet réel, une telle « modification secondaire » peut entraîner des bugs difficiles à détecter.
// Test de la structurevar person3 = PersonStruct(name: "Anna")var person4 = person3person4.name = "Marie"
print(person3.name) // Anna ! Tout est en ordreprint(person4.name) // MarieLa structure se comporte de manière prévisible : chaque variable possède sa propre copie indépendante des données. C'est sûr et transparent.
Quand Struct est-il le choix évident ?
Apple, dans sa documentation, recommande d'utiliser struct par défaut. Listons les scénarios spécifiques où la structure l'emporte sans conteste.
1. Données qui doivent être immuables
Si vous travaillez avec des modèles qui ne doivent pas changer après leur création (par exemple, les résultats d'une requête serveur), struct avec des propriétés constantes est le choix idéal.
struct UserProfile { let id: Int let name: String let email: String}
// Créé, puis oublié. Les données sont protégées contre les modifications accidentelles.let profile = UserProfile(id: 1, name: "Ivan", email: "ivan@example.com")Avec une classe, vous pourriez toujours modifier name par erreur si la propriété était déclarée comme var. Avec une structure, le compilateur vous oblige à réfléchir à l'immuabilité.
2. Entités petites et autonomes
Si votre modèle décrit quelque chose de simple — coordonnées, dimensions, couleur, somme d'argent — utilisez struct. C'est logique et efficace.
struct Point { var x: Double var y: Double}
struct Money { var amount: Double var currency: String}
struct Rectangle { var origin: Point var size: Size}Ces types n'ont pas besoin d'héritage ni de gestion des références. Ils sont simplement