Swift: شرح للStructures, Enumerations والفروق بينها وبين الClasses

Ammar AlTahhanمنذ 3 سنوات

بسم الله الرحمن الرحيم

السلام عليكم ورحمة الله وبركاته

 

في هذا الدرس سنتعرف على احد أهم الأنواع في الSwift الا وهما Structures and Enumerations.

 

أولا: Structures أو struct                                                                                                                                                                           

في Swift او اي لغة برمجة مشابهة، تعتبر الكلاسات حجر الأساس لمبدأ الObject-Oriented Programming.

بالإضافة الى الكلاسات، لدينا الStructures التي تعطينا بديل مشابه للكلاسات.

الستركتشر مشابه للكلاس، لأنه يمكن أن يحتوي على methods, properties, initializers تماما كما الكلاس، ولكن الفارق الأساسي هو ان الستركتشر يعتبر من نوع Value، والكلاسات تعتبر من نوع Reference.

 

ما معنى Value type و Reference type؟

pass-by-reference-vs-pass-by-value-animation.gif.c42292d2f8b1998f5b6a96d0d0682b6d.gif

                                                                                  صورة توضيحية للفرق بين الRegerence والValue

جميع الأنواع في الSwift هي اما عبارة عن Value type او Reference type. المتغيرات من نوع القيمة (Value type) -مثل متغيرات الInt والBool-، تقوم بنسخ قيمتها عندما يتم مساواتها بمتغير آخر

بينما متغيرات نوع المرجع (Reference type) -مثل أي اوبجكت من كلاس-، تقوم باعارة قيمتها عندما يتم مساواتها بمتغير آخر. 

لنشرح الفرق بينهم سنطرح هذا المثال البسيط لنوع القيمة:


var a: Int
var b: Int 

a=5
b=a
a=10

print(a)
print(b)

في المثال السابق، سيتم طباعة قيمتين مختلفتين لكل من a=10 و b=5، لأن قيمة a نسخت في البداية الى b حتى أصبح كل متغير يحمل قيمة خاصة ومستقلة عن المتغير الآخر، وعند تغيير قيمة a لم تتأثر قيمة b بذلك.

ولنوع المرجع لنرى المثال التالي:


var a = Car()
var b: Car

b = a
a.startCar()

b.printCarStatus()

في المثال السابق، اذا طبقنا هذا الكود فسنلاحظ أن متغير السيارة b يعمل بالفعل، أي أن قيمة a اعيرت الى b، بحيث أي تغيير يطرأ على a سيؤثر بb، وأي تغيير يطرأ على b سيؤثر بa.

 

اذا من المهم جدا أن نتذكر بأن الStructures من نوع القيمة (Value type)، بينما الClasses من نوع المرجع (Reference type).

 

اختلاف آخر صغير بين الستركتشرز والكلاسات، أن الproperties في الستركتشر لا يمكن تعديلها بطريقة مباشرة من الميثودز، بل يجب استعمال كلمة mutator لكل ميثود كي نستطيع تعديل الproperties.

مثال:


struct Circle {
    var centerX = 0.0, centerY = 0.0, radius = 1.0
    mutating func doubleRadius() {
        radius = radius * 2
    }
}

اذا أردنا مضاعفة قيمة الradius من داخل الفنكشن doubleRadius، فسنضطر لاستخدام كلمة mutator قبل الميثود، دلالة على تغيير المتغير radius بقيمة أخرى دون الحاجة لنسخه.

 

اقتباس

لنلخص الفروقات بين الستركتشرز والكلاسات:

  • الكلاسات تعتبر من نوع المرجع (Reference type)
  • الكلاسات يمكن ان تستعمل الInheritence
  • الكلاسات تستطيع تغيير الproperties الخاصة بها من داخل الميثودز دون الحاجة الى استخدام كلمة mutator

فيما عدا ذلك، فإن الستركتشرز تعتبر مشابهة تماما للكلاسات.

 

ثانيا: Enumerations او enum                                                                                                                                                                    

التعدادات (Enumerations) هي طريقة نستطيع من خلالها أن نجمع العديد من قيم المتغيرات المرتبطة ببعضها. وكما الستركتشرز، فان التعدادات تعتبر من انواع القيمة (Value type).

لنفترض بأننا نريد أن نعرف مجموعة الكواكب الشمسية، بدون استخدام التعدادات سنقوم بكتابة كود مشابه للتالي:


let mercury = 1
let venus = 2
let earth = 3
...

وبهذه الحالة سنضطر لاضاعة أسطر أخرى للتأكد من الادخال الصحيح، فمثلا لو أدخل احدهم الرقم -1:


var currentPlanet = -1 // not a valid planet!

فسيكون هناك خطأ أنتاء عمل البرنامج، ان لم نقم بكتابة if-statements مناسبة

ولكن في حالة التعدادات، يمكننا كتابتها كالتالي:


enum Planet {
    case mercury = 1 
    case venus = 2
    case earth = 3
    case mars = 4
    case jupiter = 5 
    case saturn = 6
    case uranus = 7
}

 او اختصارا:


enum Planet {
    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}

والآن، ان تم ادخال قيمة غير صحيحة:


var currentPlanet = Planet.mercury
currentPlanet = -1 // error!

فسنتعرف على الخطأ مباشرة.

 

في هذا المثال سنرى امكانية تخزين قيم مختلفة لكل case لاحقا، الآن لننشئ مجموعة الألوان الخاصة بنا:


enum Color {
    case rgb(Int, Int, Int)
    case argb(Int, Int, Int, Int)
    case cmyk(Int, Int, Int, Int)
    case name(String)
}

عند كتابة الenum بهذه الطريقة، فكأننا نخبر الSwift بأن كل case ستحصل على قيم خاصة بها لاحقا، مثل:


var blue = Color.rgb(0, 0, 255)

ويمكن استعمال الاختصار التالي عند تغيير قيمة المتغير:


var blue = Color.rgb(0, 0, 255)
blue = .argb(100, 0, 0, 255)
blue = .name("blue")

فبعد المساواة الأولى، أصبح من المعروف أن المتغير blue لن يخرج عن أحد خيارات المتعدد Color.

 

اقتباس

اذا عرفنا أن المتعددات هي طريقة لتجميع متغيرات عدة متعلقة ببعضها. ويمكن الاحتفاظ بقيم مختلفة لكل case داخل الenum.

 

وهنا نصل الى ختام موضوعنا، تقبل الله منا ومنكم صالح الأعمال

والسلام عليكم ورحمة الله

كلمات دليلية:
2
إعجاب
1949
مشاهدات
0
مشاركة
0
متابع
متميز
محتوى رهيب

التعليقات (0)

لايوجد لديك حساب في عالم البرمجة؟

تحب تنضم لعالم البرمجة؟ وتنشئ عالمك الخاص، تنشر المقالات، الدورات، تشارك المبرمجين وتساعد الآخرين، اشترك الآن بخطوات يسيرة !