Les initialisateurs échoués (init?) en Swift permettent de décrire une situation où la création d'une instance d'un type peut échouer et renvoyer nil. Ils sont souvent utilisés pour valider les données d'entrée ou pour des transformations qui peuvent ne pas réussir. Dans un init échoué, on peut explicitement renvoyer nil, indiquant un échec dans la création de l'objet.
Exemple :
struct User { let name: String let age: Int init?(name: String, age: Int) { guard !name.isEmpty, age > 0 else { return nil } self.name = name self.age = age } }
Cela permet d'éviter la création d'objets incorrects.
compactMap), c'est pratique pour filtrer les instances non valides.Question: Quelle est la différence entre init? et init! et quand utiliser un initialisateur échoué avec le déballage implicite ?
Réponse : init? renvoie un optionnel (<type?>), et si l'initialisation échoue, cela renverra nil, ce qui nécessite un traitement sécurisé. init! renvoie un optionnel déballé implicitement (<type!>), et si l'initialisation échoue, cela renverra également nil, mais l'utilisation de cet objet sans vérification entraînera un crash au moment de l'exécution. Utilisez init! uniquement si vous êtes certain que l'initialisation ne peut pas échouer dans votre contexte (par exemple, lors de l'utilisation d'un storyboard dans UIKit).
let value = Int("abc") // value sera nil
Histoire
Lors du parsing de JSON manuellement, un initialisateur normal a été utilisé au lieu d'un échoué. Cela a entraîné la création d'utilisateurs "vides", car la validation n'a pas fonctionné et l'application n'a pas filtré les données non valides.
Histoire
L'utilisation de
init!avec des données potentiellement non valides a entraîné le crash de l'application après la mise à jour de l'API : le format des données d'entrée a changé, et au moment d'extraire l'objet, une exception d'exécution est survenue en raison du déballage implicite de nil.
Histoire
Lors de la réalisation d'un init échoué personnalisé, il a été oublié de renvoyer explicitement nil pour certains scénarios, et au final, la structure a été initialisée avec des champs "sales", ce qui a ensuite causé des bugs dans la logique métier.