English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

أنواع Swift الإختيارية (Optional)

في هذا المقال، ستتعلم كيفية استخدام المفاهيم الاختيارية، أمثلة استخدامها، ومعالجة الخيارات في Swift.

في المقال السابق، تعرفنا على أنواع البيانات المتاحة في Swift، كما لاحظنا أن هذه الأنواع تحتوي على قيم افتراضية للمتغيرات أو الثوابت.

مثال:}

let someValue = Int()
print(someValue)

عند تشغيل البرنامج، الناتج هو:

0

لكن هناك أيضًا نوع بيانات آخر يُدعى Optional في Swift،والقيمة الافتراضية له هي nil. إذا كنت ترغب في عدم وجود أي قيمة في المتغير أو المستقر،يمكنك استخدام Optional. يمكن للنوع الاختياري أن يحتوي على قيمة أو لا يحتوي على أي شيء (قيمة فارغة).

تقنيًا،يمكنك اعتبارها صندوقًا اختياريًا. قد يحتوي الصندوق على حذاء أو لا يحتوي على أي شيء. لذا،عندما تريد سحب الحذاء من الصندوق،يجب أن تعرف مسبقًا.

كيفية إعلان اختياري؟

يمكنك ببساطة تمثيل البيانات كاختياري عبر إضافة. الطريقة هي إضافة ! أو?. إذا كان يحتوي المتغير الاختياري على قيمة،فسيتم إرجاع قيمته كـ Optional <Value>،وإلا سيتم إرجاع nil.

مثال 1:كيفية إعلان اختياري في Swift؟

var someValue:Int?
var someAnotherValue:Int!
print(someValue)
print(someAnotherValue)

عند تشغيل البرنامج، الناتج هو:

nil
nil

في البرنامج المذكور أعلاه،نحن نستخدم ? و! لتحديد نوع اختياري. كلا الطريقتين يمكنهما إنشاء نوع اختياري،لكن هناك فرق رئيسي سنستعرضه لاحقًا.

إعلان اختياري Int يعني أن المتغير سيكون له قيمة عددية أو لا قيمة. لأن لا يتم تخصيص أي قيمة للمتغير،لذا يمكنك رؤية اثنين من طبعات print nil على الشاشة.

مثال 2:تخصيص وتواصل القيمة من عنصر اختياري

let someValue:Int? = 5
print(someValue)
print(someValue!)

عند تشغيل البرنامج، الناتج هو:

Optional(5)
5

في البرنامج المذكور أعلاه،نحن نعلن عن نوع اختياري Int ونقوم بتخصيص القيمة 5.

عندما تضيف طبعًا someValue إلى print(someValue) لن يعطيك 5،بل Optional(5). إنه له نفس الشكل المذكور أعلاه:Optional <Value>. للاستفادة من <Value>،نحتاج إلى شيء يُدعى تفريغًا.التفريغالآلية.

يمكنك فتح محتوى الاختياري عبر إضافة رمز ! في نهاية المتغير/المستقر،كما هو موضح في السطر التالي print(someValue!).print(someValue!) يفتح محتوى الاختياري ويقوم بطباعة 5 على الشاشة.

لكن تذكر،استخدم هذا آلية التفريغ فقط عندما تكون متأكدًا من أن لديك قيمة عند الوصول إلى الخيار الاختياري.

مثال 3:إعلان اختياري غير معبأ بوضوح

يمكنك أيضًا إنشاء محتوى اختياري مفتوح عبر الطريقة التالية:

let someValue:Int! = 5
print(someValue)

عند تشغيل البرنامج، الناتج هو:

5

في البرنامج المذكور أعلاه،Int! ي 创建 محتوى اختياري غير معبأ،عندما تصل إليه،يتم تفريغ القيمة تلقائيًا،لذا لا تحتاج إلى استخدام رمز! في كل مرة.

请确保在使用这些可选选项时,变量在访问时始终需要有一个值。如果不这样做,将会导致致命的错误崩溃。

تأكد من أن المتغيرات دائمًا تحتاج إلى قيمة عند استخدام هذه الخيارات الإضافية. إذا لم تفعل ذلك، ستؤدي إلى خطأ حاسم يؤدي إلى إسقاط البرنامج.

var someValue:Int!
مثال 4: خطأ حاسم عند الوصول إلى عنصر null في العنصر الإضافي

var unwrappedValue: Int = someValue // يُسقط بسبب هذا السطر

عند تشغيل هذا البرنامج، ستحصل على خطأ حاسم يؤدي إلى إسقاط البرنامج: تم العثور على nil غير متوقع عند فك الـ Optional، لأن الكود unwrappedValue: Int = someValue يحاول تخصيص القيمة من Optional someValue إلى المتغير unwrappedValue.

لكن، somevalue هو نوع إضافي يحتوي على قيمة nil. سيؤدي محاولة تخصيص قيمة nil لهذا المتغير unwrappedValue (ليس Optional) إلى إسقاط البرنامج.

سيتم شرح الطرق المختلفة لمعالجة هذه الحالة.

معالجة التحكم في الخيار

للبدء في استخدام القيم الإضافية، يجب تفريغها. أفضل طريقة لاستخدام القيم الإضافية هي التفريغ المعتمد، وليس التفريغ القسري باستخدام عملاق !.ذلك لأن التوسع المعتمد يطرح سؤالاًهل يجب التحقق مما إذا كان هذا المتغير يحتوي على قيمة؟

على العكس من ذلك، التوسع القسري يعني أن هذا المتغير له قيمة فعلياً عند استخدامه. لذلك، عند توسيع متغير nil قسرياً، سيقوم برنامجك بتسليم استثناء Optional غير متوقع وسيتم إسقاط خطأ.

1. جملة if

يمكنك استخدام جملة if لتحقق مما إذا كان المعامل الإضافي يحتوي على قيمة، يمكنك استخدام محدديات الحساب "المساواة" (==) أو "التفاوت" (!=) في جملة if.

مثال 5: معالجة التحكم في الخيار باستخدام جملة if else

var someValue:Int?
var someAnotherValue:Int! = 0
        
if someValue != nil {
	print("يحتوي على قيمة \(someValue!)")
}
	print("لا يحتوي على قيمة")
}
        
if someAnotherValue != nil {
	print("يحتوي على قيمة \(someAnotherValue!)")
}
	print("لا يحتوي على قيمة")
}

عند تشغيل البرنامج، الناتج هو:

لا يحتوي على قيمة
يحتوي على قيمة 0

في البرنامج المذكور أعلاه، إذا كان جملة الخيار يحتوي على قيمة، يتم تنفيذ الكود الموجود داخل جملة if، وإلا يتم تنفيذ الكود الموجود داخل جملة else.

2. التحكم في الخيار (if let)

التحكم في الخيار يمكن أن يساعدك في العثور على ما إذا كان يحتوي الخيار الإضافي على قيمة. إذا كان يحتوي الخيار الإضافي على قيمة، فإن هذه القيمة يمكن استخدامها كمعلمة مؤقتة أو متغير. لذلك، يمكن استخدام التحكم في الخيار مع جملة if لتحقق من القيمة الداخلية والاستخراج منها كمعلمة أو متغير في عملية واحدة.

مثال 5: استخدام جملة if let لمعالجة الخيار

var someValue:Int?
var someAnotherValue:Int! = 0
       
if let temp = someValue {
	print("يحتوي على قيمة \(temp)") 
}
	print("لا يحتوي على قيمة")
}
        
if let temp = someAnotherValue {
	print("يحتوي على قيمة \(temp)")
}
	print("لا يحتوي على قيمة")      
}

عند تشغيل البرنامج، الناتج هو:

لا يحتوي على قيمة
يحتوي على قيمة 0

في البرنامج أعلاه، إذا كان الخيار يحتوي على قيمة، يتم تنفيذ الكود في جملة if. وإذا لم يحتوي على قيمة، يتم تنفيذ قوس else. كما أن جملة if-let تقوم تلقائيًا بتفريغ القيمة وتخزينها في المتغير temp. يعتبر هذا الأسلوب ميزة رئيسية لأنك يمكنك التأكد من أن الخيار يحتوي على قيمة دون الحاجة إلى تفريغ القيمة بشكل قسري.

3. جملة Guard

يمكنك أيضًا استخدام جملة guard في Swift لمعالجة محتويات الخيار. إذا لم تكن تعلم ما هو guard، لا تقلق. الآن، اعرض guard كـ if-else بدون if تمنع. إذا فشلت الشروط، يتم تنفيذ جملة else. إذا لم تفشل، يتم تنفيذ الجملة التالية. لمزيد من التفاصيل، راجع.Swift Guard.

مثال 6: استخدام Guard لمعالجة الخيار

func testFunction() {
	let someValue:Int? = 5
	guard let temp = someValue else {
		return
	}
	print("It has some value \(temp)")
}
testFunction()

عند تشغيل البرنامج، الناتج هو:

It has some value 5

في البرنامج أعلاه، يحتوي guard على شرط، وهو ما إذا كان someValue يحتوي على قيمة. إذا كان يحتوي على قيمة، فإن جملة guard-let ستقوم تلقائيًا بتفريغ القيمة وتخزينها في المتغير temp. وإلا سيتم تنفيذ قوس else، وسيعود إلى الدالة المُتدعاة. لأن الخيار يحتوي على قيمة، يتم استدعاء دالة print. لمزيد من التفاصيل، راجع Swift guard.

4. عميل التجميع (??)

في Swift، يمكنك أيضًا استخدام عميل التجميع لتحقق من ما إذا كان الخيار يحتوي على قيمة. يتم تعريفه كـ (a??b). يفتح الخيار a، إذا كان يحتوي على قيمة، فيقوم بتحويله، أو إذا كان a فارغًا، فيقوم بتحويله إلى القيمة الافتراضية b.

مثال 7: استخدام عميل التجميع الخيار

var someValue:Int!
let defaultValue = 5
let unwrappedValue: Int = someValue ?? defaultValue
print(unwrappedValue)

عند تشغيل البرنامج، الناتج هو:

5

في البرنامج المذكور أعلاه، تم تعريف المتغير someValue كمتغير اختياري يحتوي على القيمة nil. لذلك، لا يمكن تفكير في القيمة الإختيارية، ويعود defaultValue. لذلك، أخرجت جملة print(unwrappedValue) القيمة 5 في وحدة التحكم.

var someValue: Int? = 10
let defaultValue = 5
let unwrappedValue: Int = someValue ?? defaultValue
print(unwrappedValue)

عند تشغيل البرنامج، الناتج هو:

10

لكن، في البرنامج المذكور أعلاه، تم تثبيت المتغير الإختياري someValue على القيمة 10. لذلك، تم تفعيل محاولات التفكير في القيمة someValue بنجاح. لذلك، عادت الجملة someValue ?? defaultValue في وحدة التحكم 10، وأخرجت جملة print(unwrappedValue) القيمة 10.