مساحة اعلانية

آخر المواضيع

نصيحة سريعة: المتعددات في Swift

نصيحة سريعة: المتعددات في Swift
نصيحة سريعة: المتعددات في Swift

تعد المتعددات نمط تصميم شائع مستخدم في عدة لغات برمجة. في حين أنك لربما تعرف عن المتعددات في C وفي Objective-C ، فإن تطبيق Swift للمتعددات يعتبر أكثر فعالية ومرونة بشكل ملحوظ. في هذه النصيحة السريعة، ستتعلم ما هو الشيء المميز بالمتعددات في Swift ، كيفية إستخدامهم في مشاريعك، وما هو الشيء الذي يجعلهم فعالين.





1. ما هي المتعددات ؟

لا تعد المتعددات شيئاً جديداً وليست حكراً لدى Swift فقط. ولكن إذا كنت ممن لديه معرفة بالمتعددات في C ، فإنك ستحب المتعددات الفعالة في Swift.

إذا كنت ممن لا يعرف أي شيء عن enums أو المتعددات، فمن الممكن أنك لا تعرف ماذا يمكنهم أن يفعلوا. المتعددات في Swift هم عبارة عن أنواع من الصنف الأول تقوم بتعريف قائمة من القيم المحتملة لهذا النوع.

وقد تشكل حالات محتملة من اتصال الشبكة مثالاً ممكناً. يمكن أن تكون الحالات المحتملة:
  • غير متصل 
  • جاري الاتصال
  • متصل

ويمكن إضافة حالة رابعة لهذا المثال وهي غير معروف. تذكر هذا المثال ودعنا نرى كيفية تعرف وتطبيق المتعددات.


الأساسيات

وكما قلت تعد المتعددات أنواعاً من الصنف الأول في Swift يشبه تعريف المتعددات تعريف الصنف أو تعريف البنية. في المثال أسفلاً، سنقوم بتعريف متعددات ConnectionState.


enum ConnectionState {
}

يسبق اسم المتعددات بـ: كلمة enum الأساسية ويتبع بـزوج من الأقواس المعوجة كما في المثال. ستقوم متعددات ConnectionState بتعريف حالات ممكنة لاتصال الشبكة. لتعريف هذه الحالات سنضيف أعضاء ذات قيمة أو أعضاء لتعريف المتعددات. دائماً ما يبدأ تعريف العضو ذات القيمة بـكلمة حالة الأساسية.    


enum ConnectionState {
    case Unknown
    case Disconnected
    case Connecting
    case Connected
}

في كل من C و Objective-C ، سيبدو المتعدد مختلفاً قليلاً كما هو موضح في المقال أسفلاً. ستتوافق كل قيمة من قيم المتعددات مع رقم، على سبيل المثال، ConnectionStateUnknown تساوي 0 ، ConnectionStateDisconnected تساوي 1 ، .. إلخ.
   

typedef enum : NSUInteger {
    ConnectionStateUnknown,
    ConnectionStateDisconnected,
    ConnectionStateConnecting,
    ConnectionStateConnected
} ConnectionState;

هذا لا ينطبق على Swift . لا يتوافق أعضاء المتعددات بشكل أوتوماتيكي مع قيمة رقمية. تعد أعضاء متعددات ConnectionState قيماً بحد ذاتها وهي من نوع ConnectionState . وهذا ما يجعل العمل مع المتعددات أكثر سهولة و وضوحاً.


القيم الخام

من الممكن تحديد قيم أعضاء المتعددات بوضوح. في المثال التالي، هنالك متعددات ConnectionState ذات قيمة خام من نوع Int . يتم تعيين قيمة خام لكل عضو، متوافقاً مع رقم.

enum ConnectionState: Int {
    case Unknown = -1
    case Disconnected = 0
    case Connecting = 1
    case Connected = 2
}

لاحظ أننا قمنا بتحديد نوع قيم خام في تعريف المتعددات وأنه لا يمكن لعضوين أن يأخذا نفس قيمة خام. إذا قمنا فقط بتحديد قيمة لعضو غير معروف، فإن Swift سيقوم أتوماتيكياً بزيادة قيمة العضو Unknown وتعيين قيم فريدة من نوعها لأعضاء المتعددات الأخرى. ولتوضيح ذلك أكثر، فإن المثال أسفلاً يطابق تماماً تعريف متعددات ConnectionState السابق.


enum ConnectionState: Int {
    case Unknown = -1
    case Disconnected
    case Connecting
    case Connected
}


2. العمل مع المتعددات



Initialization (البدأ)

يعتبر استخدام متعددات ConnectionState مشابهاً لأي نوع آخر في Swift في المثال التالي، سنعلن عن متغير، connectionState ، ونضع ConnectionState.Connecting قيمة له.


var connectionState = ConnectionState.Connecting

تعتبر ConnectionState.Connecting قيمة لـ: connectionState. ويعد المتغير من نوع ConnectionState.

يعد استدلال نوع Swift مريح جداً عند العمل مع المتعددات. لأننا قلنا أن connectionState هي عبارة عن نوع ConnectionState ، فإنه بإمكاننا الآن أن نعين قيمة جديدة من خلال استخدام تركيبة كود النقطة للمتعددات.


connectionState = .Connected


التحكم بالتدفق

يعتبر استخدام المتعددات في عبارة إذا أو في تقرير Swift بسيطاً جداً. تذكر أنه يجب على تقارير Swift أن تكون كاملة. أضف حالة افتراضية (default) إذا استلزم الأمر.


enum ConnectionState {
    case Unknown
    case Disconnected
    case Connecting
    case Connected
}

var connectionState = ConnectionState.Connecting
connectionState = .Connected

switch connectionState {
    case .Disconnected:
        println("Disconnected")
    case .Connecting:
        println("Connecting")
    case .Connected:
        println("Connected")
    default:
        println("Unknown State")
}


يعرض المثال التالي كيفية استخدام ConnectionState enum . ويوضح أيضاً كيفية الولوج إلى القيمة المرتبطة بعضو enum . تقوم canConnect function بقبول نموذج ConnectionState وتعيده كـ: Bool.


func canConnect(connectionState: ConnectionState) -> Bool {
    var result = false
    
    switch connectionState {
        case .Connected(let port):
            if port == 3000 {
                result = true
            }
        default:
            result = false
    }
    
    return result
}

let state = ConnectionState.Connected(3000)
if canConnect(state) {
    // ...
}

عود canConnect function صحيحة فقط إذا كان نموذج ConnectionState  الذي تم تمريره إلى function مساوياً له. يعد المتصل والقيمة المرتبطة به Int مساوياً لـ: 3000 لاحظ أن القيمة المرتبطة بالعضو Connected ظاهرة بتقرير Swift كمنفذ مسمى دائم، الذي يمكن حينئذ استخدامه في الحالة المتوافقة.


3. القيم المرتبطة

تعد القيم المرتبطة ميزة أخرى مشوقة في Swift enum يمكن لكل عضو من enum أن يكون لديه قيمته الخاصة المرتبطة به. تعد القيم المرتبطة مرنة جداً. مثلاً لا يجب على القيم المرتبطة التابعة لأعضاء مختلفين من نفس enum أن يكونوا من نفس النوع. للفهم أكثر مفهوم القيم المرتبطة، ألق نظرة على المثال التالي:



enum ConnectionState {
    case Unknown
    case Disconnected
    case Connecting(Int, Double)
    case Connected(Int)
}

لا يجب على الأعضاء Unknown و Disconnected أن يكون لديهم قيم مرتبطة. ولكن لدى عضو Connecting قيمة من نوع Int) Double)، وهي تحدد رقم المنفذ وفترة إنتهاء مدة الاتصال. لدى عضو Connected قيمة مرتبطة من نوع Int ، وهي تحدد رقم المنفذ.

من الضروري فهمه إن القيمة المرتبطة تتصل أو ترتبط بعضو من المتعددات. وتبقى قيمة العضو ثابتة وغير متغيرة. يوضح المثال التالي كيفية إبتكار نموذج ConnectionState مع قيمة مرتبطة.


var connectionState = ConnectionState.Connecting(3000, 30.0)


4. الطرق وأنواع القيم



الطرق

تعتبر المتعددات فعالة جداً في Swift يمكن للمتعددات حتى أن تعرف الطرق، كـ: initializer من أجل إختيار عضو افتراضي (default) إذا لم يكن أيها محدداً.

enum ConnectionState {
    case Unknown
    case Disconnected
    case Connecting(Int, Double)
    case Connected(Int)
    init () {
        self = .Unknown
    }
}

var connectionState = ConnectionState() // .Unknown

في هذا المثال، سنبدأ بنموذج من متعددات ConnectionState من دون تحديد قيمة لها بشكل واضح. ولكن في initializer المتعددات سنضع النموذج Unknown. وتكون النتيجة أن متغير connectionState مساوياً لـ: ConnectionState.Unknown.


أنواع القيم

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

var connectionState1 = ConnectionState()
var connectionState2 = connectionState1
connectionState1 = .Connected(1000)
println(connectionState1) // .Connected(1000)
println(connectionState2) // .Unknown


على الرغم من أننا نعين connectionState1 لـ: connectionState2 ، فإن قيم connectionState1 و connectionState2 تصبح مختلفة في نهاية المثال.

عندما نقوم بتعيين connectionState1 لـ: connectionState2 ، فإن Swift يبتكر نسخة عن connectionState1 ويقوم بتعيينها لـ: connectionState2 . وبكلمات أخرى، فإن كلا من connectionState1 و connectionState2 ترجع لنموذجين مختلفين من ConnectionState.


الخلاصة

تعد المتعددات فعالة جداً في Swift بالمقارنة مع المتعددات في C على سبيل المثال. إن واحدة من أهم مظاهر المتعددات هي أنها من أنواع الصنف الأول في Swift . يعد نوع الأمان من أهم مظاهر لغة ومتعددات Swift التي تناسب بشكل تام تلك الثوابت.

الكــاتــب

    • مشاركة

ليست هناك تعليقات:

جميع الحقوق محفوظة لــ الشبح للمعلوميات 2019 ©