0Pricing
Swift Academy · درس

التحويل الشرطي باستخدام as?

جرّب تحويلًا يعيد قيمة اختيارية عند الفشل.

التحويل الشرطي باستخدام as? درس مجاني في Swift Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Swift Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Swift Academy 4 دروس في المجموع.

التحويل الشرطي

يحاول معامل التحويل الشرطي as? إجراء تحويل تنازلي ويُرجع قيمة اختيارية: تكون القيمة داخلها عند نجاح التحويل، أو nil عند فشله.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
let maybe = a as? Dog
print(maybe != nil)

النتيجة قيمة اختيارية

نظرًا إلى احتمال فشل التحويل، يكون نوع النتيجة Dog? وليس Dog. ويجب فك تغليفها قبل استخدامها.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
let maybe: Dog? = a as? Dog
print(type(of: maybe))

فك التغليف باستخدام if let

الطريقة الاصطلاحية لاستخدام as? هي وضعه داخل ربط if let، الذي ينفذ الجسم فقط عند نجاح التحويل.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
if let dog = a as? Dog {
    print(dog.bark())
} else {
    print("Not a dog")
}

يعيد التحويل الفاشل nil

عندما لا يكون المثيل من النوع الهدف، يُنتج as? القيمة nil، ويُتخطى جسم if let.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Cat(name: "Mia")
if let dog = a as? Dog {
    print(dog.bark())
} else {
    print("That is not a dog")
}

الدمج مع guard let

يمكنك أيضًا استخدام guard let لإجراء التحويل مبكرًا والخروج عند فشله، مع إبقاء المسار الأساسي دون زيادة في الإزاحة.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
func describe(_ a: Animal) {
    guard let cat = a as? Cat else {
        print("Not a cat")
        return
    }
    print(cat.meow())
}
describe(Cat(name: "Mia"))
describe(Dog(name: "Rex"))

التحويل الشرطي داخل الحلقات

يُعد تكرار مصفوفة مختلطة وتحويل كل عنصر فيها شرطيًا طريقة واضحة وآمنة للتعامل مع الأصناف الفرعية المختلفة.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let zoo: [Animal] = [Dog(name: "Rex"), Cat(name: "Mia"), Dog(name: "Buddy")]
for a in zoo {
    if let dog = a as? Dog {
        print(dog.bark())
    }
}

التحويل إلى البروتوكولات

يتحقق as? أيضًا من امتثال المثيل لبروتوكول؛ إذ يُرجع قيمة إذا كان المثيل ممتثلًا للبروتوكول، وإلا يُرجع nil.

protocol Greeter { func greet() -> String }
class Person: Greeter { func greet() -> String { return "Hi" } }
class Rock {}
let items: [Any] = [Person(), Rock()]
for item in items {
    if let g = item as? Greeter { print(g.greet()) }
}

الدمج مع nil بعد التحويل

يمكنك إقران as? بالمعامل ?? لتوفير قيمة بديلة عند فشل التحويل.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Cat(name: "Mia")
let sound = (a as? Dog)?.bark() ?? "unknown sound"
print(sound)

تسلسل استدعاءات التحويل الاختياري

يتيح لك التسلسل الاختياري استدعاء طريقة على نتيجة التحويل؛ ويكون التعبير بأكمله nil إذا فشل التحويل.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
let bark = (a as? Dog)?.bark()
print(bark as Any)

لماذا يُفضَّل التحويل الشرطي

لا يتسبب as? في أي انهيار؛ فالتحويل الفاشل يُنتج ببساطة nil. لذلك فهو الخيار الآمن الافتراضي للتحويل التنازلي.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let unknown: Animal = Cat(name: "Mia")
let result = unknown as? Dog
print("Crashes? No. Value is nil:", result == nil)

مثال ملخص على التحويل الشرطي

بتجميع الخطوات: اكتشف نوعًا فرعيًا بأمان، وتعامل معه، ثم ارجع بسلاسة إلى بديل عند عدم نجاح ذلك.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
func sound(of a: Animal) -> String {
    if let d = a as? Dog { return d.bark() }
    if let c = a as? Cat { return c.meow() }
    return "silence"
}
print(sound(of: Dog(name: "Rex")))
print(sound(of: Cat(name: "Mia")))

اختبار سريع

تذكّر نوع نتيجة التحويل الشرطي.

مراجعة: التحويل الشرطي باستخدام as?

لقد تعلمت أن as? يُجري تحويلًا تنازليًا آمنًا ويُرجع قيمة اختيارية، وأن if let وguard let يفكان تغليف حالة النجاح، وأنه لا يتسبب في أي انهيار لأن الفشل يُنتج ببساطة nil، مما يجعله معامل التحويل التنازلي المفضّل.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let pets: [Animal] = [Dog(name: "Rex"), Cat(name: "Mia")]
for p in pets {
    if let d = p as? Dog { print(d.bark()) } else if let c = p as? Cat { print(c.meow()) }
}

الأسئلة الشائعة

هل درس «التحويل الشرطي باستخدام as?» مجاني؟

نعم — نص درس «التحويل الشرطي باستخدام as?» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Swift Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Swift Academy 4 دروس في المجموع.

ماذا ستتعلم في «التحويل الشرطي باستخدام as?»؟

جرّب تحويلًا يعيد قيمة اختيارية عند الفشل. تتمرن على Swift Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Swift Academy؟

لا تُشترط خبرة سابقة. Swift Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «التحويل الشرطي باستخدام as?»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Swift Academy هذا؟

نعم. كل درس في Swift Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. أساسيات التحويل إلى النوع الأب والتحويل إلى النوع الابن
  2. التحويل الشرطي باستخدام as?
  3. التحويل الإجباري باستخدام as! ومخاطره
  4. التحقق من الأنواع باستخدام is
← العودة إلى Swift Academy