Initialiseurs pouvant échouer
Fait partie de la section Programmation orientée objet du Journey Swift de Coddy. Leçon 20 sur 57.
Certaines valeurs ne peuvent pas être construites à partir de toutes les entrées. Un initialiseur pouvant échouer, écrit init?, renvoie nil au lieu d’une instance lorsque l’entrée n’est pas valide, de sorte qu’aucune instance invalide ne puisse jamais exister :
struct Percentage {
let value: Int
init?(_ value: Int) {
guard value >= 0, value <= 100 else { return nil }
self.value = value
}
}
print(Percentage(42)?.value ?? -1)
print(Percentage(150)?.value ?? -1)Résultat :
42
-1Le résultat d’un initialiseur susceptible d’échouer est une valeur optionnelle ; l’appelant doit donc la déballer, généralement avec if let ou guard let :
struct Email {
let address: String
init?(_ text: String) {
let parts = text.split(separator: "@")
guard parts.count == 2, parts[1].contains(".") else { return nil }
address = text.lowercased()
}
}
for text in ["Ada@Mail.com", "not-an-email"] {
if let email = Email(text) {
print("valid: \(email.address)")
} else {
print("invalid: \(text)")
}
}Sortie :
valid: ada@mail.com
invalid: not-an-emailLes propres types de Swift utilisent la même idée : Int("42") et Double("x") sont des initialiseurs pouvant échouer, tout comme init(rawValue:) d'une énumération. Un initialiseur pouvant échouer peut les appeler et transmettre l'échec :
struct Coordinate {
let lat: Double
let lon: Double
init?(text: String) {
let parts = text.split(separator: ",")
guard parts.count == 2,
let lat = Double(parts[0]), let lon = Double(parts[1]),
abs(lat) <= 90, abs(lon) <= 180 else { return nil }
self.lat = lat
self.lon = lon
}
}
print(Coordinate(text: "51.5,-0.1") != nil)
print(Coordinate(text: "95,10") != nil)Résultat :
true
falseUtilisez init? lorsqu’une valeur manquante constitue une information suffisante. Utilisez un initialiseur lançant une erreur, init(...) throws, lorsque l’appelant doit savoir quelle règle a échoué :
struct Username {
let text: String
init(_ text: String) throws {
guard text.count >= 3 else { throw NameError.tooShort }
guard text.allSatisfy({ $0.isLetter }) else { throw NameError.badCharacters }
self.text = text
}
}Défi
FacileComplétez la structure Rgb, qui stocke une couleur sous la forme de red, green et blue compris entre 0 et 255. Son initialiseur pouvant échouer init?(hex:) lit un texte tel que #FF8000 : il renvoie nil sauf si le texte est constitué de # suivi exactement de six chiffres hexadécimaux. Utilisez Int(text, radix: 16) pour chaque paire. Ajoutez une label calculée qui renvoie rgb(255, 128, 0).
Le code fourni lit une couleur par ligne et affiche le libellé ou invalid: text.
Votre code doit être placé dans Rgb.swift. main.swift contient le code d’entrée/sortie fourni et ne peut pas être modifié.
Essayez vous-même
// Code d'entrée/sortie fourni : le garder tel quel
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in input {
if let color = Rgb(hex: line) {
print(color.label)
} else {
print("invalid: \(line)")
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation orientée objet
1Classes et objets
Travailler avec des fichiersDéfinir des classesMéthodes et selfInitialiseursLes classes sont des référencesRécapitulatif - Carte de bibliothèque4Encapsulation
Contrôle d’accèsLecture seule depuis l’extérieurProtection de l’étatInitialiseurs pouvant échouerRécapitulatif - Compte bancaire7Polymorphisme et génériques
PolymorphismeConversion de typeFonctions génériquesTypes génériquesRécapitulatif - Calculateur de formes2Structures et types valeur
StructuresSémantique de valeurMéthodes mutantesStructure ou classeRécapitulatif - article d’inventaire5Héritage
Sous-classesRedéfinition des méthodesInitialiseurs et superfinal et hiérarchiesRécapitulatif - hiérarchie des employés8Protocoles standard
CustomStringConvertibleEquatableComparableHashableRécapitulatif - Tri personnalisé11Projet : Gestion de bibliothèque
Livres et membresEmprunter des livresEntraînez-vous par vous-même : Playground Swift