المهيئات القابلة للفشل
جزء من قسم البرمجة كائنية التوجه في رحلة Swift على Coddy. الدرس 20 من 57.
لا يمكن إنشاء بعض القيم من كل إدخال. المُهيّئ القابل للفشل، المكتوب بصيغة init?، يُرجع nil بدلًا من نسخة عند كون الإدخال غير صالح، لذلك لا يمكن أن توجد نسخة غير صالحة أبدًا:
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)الناتج:
42
-1نتيجة المُهيئ القابل للفشل هي قيمة اختيارية، لذا يجب على المستدعي فك تغليفها، عادةً باستخدام if let أو 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)")
}
}المخرجات:
valid: ada@mail.com
invalid: not-an-emailتستخدم أنواع Swift الخاصة بها الفكرة نفسها: Int("42") وDouble("x") هما مُهيِّئان قابلان للفشل، وكذلك مُهيِّئ التعداد init(rawValue:). ويمكن لمُهيِّئ قابل للفشل استدعاء هذه المُهيِّئات وتمرير الفشل:
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)الناتج:
true
falseاستخدم init? عندما تكون القيمة المفقودة معلومات كافية. استخدم مُهيئًا يُطلق خطأً، init(...) throws، عندما ينبغي للمتصل معرفة القاعدة التي فشلت:
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
}
}التحدي
سهلأكمل البنية Rgb، التي تخزّن لونًا على هيئة red وgreen وblue من 0 إلى 255. يقرأ المهيئ القابل للفشل init?(hex:) نصًا مثل #FF8000: ويُرجع nil ما لم يكن النص هو # متبوعًا بستة أرقام سداسية عشرية بالضبط. استخدم Int(text, radix: 16) لكل زوج. أضف label محسوبة تُرجع rgb(255, 128, 0).
يقرأ الكود المزوّد لونًا واحدًا في كل سطر ويطبع التسمية أو invalid: text.
ضع كودك في Rgb.swift. يحتوي main.swift على كود الإدخال/الإخراج المزوّد، ولا يمكن تعديله.
جرّب بنفسك
// كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
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)")
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الأصناف والكائنات
العمل مع الملفاتتعريف الأصنافالأساليب وselfالمُهيِّئاتالأصناف هي مراجعمراجعة - بطاقة المكتبة4التغليف
التحكم في الوصولللقراءة فقط من الخارجحماية الحالةالمهيئات القابلة للفشلمراجعة - الحساب البنكي7تعدد الأشكال والأنواع العامة
تعدد الأشكالتحويل الأنواعالدوال العامةالأنواع العامةمراجعة - حاسبة الأشكالتدرّب بنفسك: Playground لـ Swift