Failable initializers (init?) in Swift maken het mogelijk om een situatie te beschrijven waarin het maken van een instantie van een type kan mislukken en nil kan teruggeven. Ze worden vaak gebruikt voor het valideren van invoergegevens of conversies die mogelijk niet succesvol zijn. In een failable initializer kan expliciet nil worden geretourneerd om aan te geven dat het maken van het object is mislukt.
Voorbeeld:
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 } }
Hierdoor kan worden voorkomen dat ongeldige objecten worden gemaakt.
compactMap) plaatsvindt, is dit handig voor het filteren van ongeldige instanties.Vraag: Wat is het verschil tussen init? en init! en wanneer moet je een failable initializer met impliciete unwrapping gebruiken?
Antwoord: init? geeft een optioneel terug (<type?>), en als de initialisatie mislukt, wordt nil geretourneerd, wat veilige verwerking vereist. init! geeft een implicitly unwrapped optional terug (<type!>), en als de initialisatie mislukt, wordt ook nil geretourneerd, maar het gebruik van zo'n object zonder controle leidt tot een runtime-crash. Gebruik init! alleen als je er zeker van bent dat de initialisatie in jouw context niet kan mislukken (bijvoorbeeld bij werken met storyboard in UIKit).
let value = Int("abc") // value zal nil zijn
Verhaal
Bij het handmatig parseren van JSON werd een gewone initializer gebruikt in plaats van een failable. Dit leidde tot het maken van "lege" gebruikers, omdat de validatie niet werkte en de applicatie geen ongeldige gegevens filterde.
Verhaal
Het gebruik van
init!met potentieel ongeldige gegevens leidde tot een crash van de applicatie na een API-update: het formaat van de invoergegevens was veranderd, en op het moment van uitlezen van het object trad er een runtime-exceptie op door onterecht unwrapping van nil.
Verhaal
Bij de aangepaste implementatie van een failable init werd vergeten om expliciet nil terug te geven voor bepaalde scenario's, waardoor de struct werd geïnitialiseerd met "vuile" velden, wat later bugs in de bedrijfslogica veroorzaakte.