يبلغ عمر لغة برمجة 
Swift أربعة أعوام فقط ، لكنها أصبحت بالفعل لغة التطوير الرئيسية لنظام التشغيل iOS. تطور إلى الإصدار 5.0 ، أصبح Swift لغة معقدة وقوية تلبي نموذجًا موجهًا للكائنات ونموذجًا وظيفيًا. ومع كل إصدار جديد ، فإنه يضيف المزيد من الميزات.
لكن إلى أي مدى تعرف سويفت 
حقًا ؟ في هذه المقالة ، ستجد أسئلة نموذجية لمقابلة سويفت.
يمكنك استخدام هذه الأسئلة لمقابلة المرشحين لاختبار معرفتهم أو يمكنك اختبار معلوماتك الخاصة. إذا كنت لا تعرف الإجابة ، فلا تقلق: فهناك إجابة لكل سؤال.
يتم تقسيم الأسئلة إلى ثلاث مجموعات:
- المبتدئين : للمبتدئين. تقرأ بضعة كتب وطبقت تطبيق سويفت في تطبيقاتك الخاصة.
- متوسط : مناسب لأولئك الذين يهتمون حقًا باللغة. لقد قرأت بالفعل الكثير عن ذلك وتجربته غالبًا.
- متقدم : مناسب للمطورين الأكثر تقدمًا - أولئك الذين يحبون الدخول في غابة بناء الجملة واستخدام التقنيات المتقدمة.
هناك نوعان من الأسئلة لكل مستوى:
- مكتوبة : مناسبة للاختبار عن طريق البريد الإلكتروني ، لأنها تشير إلى كتابة التعليمات البرمجية.
- شفهيًا : يمكن استخدامه عند التحدث على الهاتف أو شخصيًا ، حيث توجد إجابة كافية بالكلمات.
أثناء قراءة هذا المقال ، 
اجعل الملعب مفتوحًا حتى تتمكن من التحقق من الكود من السؤال. تم اختبار جميع الإجابات على 
Xcode 10.2 و 
Swift 5 .
- مبتدئ
 - أسئلة مكتوبة- السؤال 1- النظر في التعليمات البرمجية التالية: - struct Tutorial { var difficulty: Int = 1 } var tutorial1 = Tutorial() var tutorial2 = tutorial1 tutorial2.difficulty = 2
 - ما هي قيم  tutorial1.difficulty-  و  tutorial2.difficulty-  ؟ هل سيكون هناك أي فرق إذا كان  البرنامج التعليمي-  صفًا؟ لماذا؟ - الجواب- tutorial1.difficulty هو 1 ، و tutorial2.difficulty هو 2. - في Swift ، تكون الهياكل أنواع قيمة. يتم نسخها ، وليس الرجوع إليها. السطر التالي بنسخ  tutorial1-  وتعيينه إلى  tutorial2-  : -  - var tutorial2 = tutorial1
 - لا تؤثر التغييرات في  tutorial2-  على  tutorial1-  . - إذا كان البرنامج التعليمي عبارة عن فصل  دراسي-  ، فسوف تساوي  tutorial1.difficulty-  و  tutorial2.difficulty-  2. والفئات في Swift هي أنواع مرجعية. عندما تقوم بتغيير خاصية tutorial1 ، سترى نفس التغيير لبرنامج tutorial2 - والعكس بالعكس. 
 
 - السؤال 2- أعلنت  view1-  مع  var-  و  view2-  مع  اسمحوا-  . ما هو الفرق ويتم تجميع السطر الأخير؟ -  - import UIKit var view1 = UIView() view1.alpha = 0.5 let view2 = UIView() view2.alpha = 0.5 
 - الجواب- نعم ، يتم تجميع السطر الأخير.  view1-  متغير ، ويمكنك تعيين قيمته لمثيل جديد لـ UIView. باستخدام  اسمحوا-  ، يمكنك فقط تعيين قيمة مرة واحدة ، لذلك لا يتم ترجمة التعليمات البرمجية التالية: -  - view2 = view1 
 - ومع ذلك ، فإن UIView هي فئة ذات دلالات مرجعية ، بحيث يمكنك تغيير خصائص view2 - مما يعني أن الشفرة  ستترجم-  . 
 
 - السؤال 3- يفرز هذا الكود الصفيف أبجديًا. تبسيط الإغلاق قدر الإمكان. -  - var animals = ["fish", "cat", "chicken", "dog"] animals.sort { (one: String, two: String) -> Bool in return one < two } print(animals)
 - الجواب- يحدد-  Swift  تلقائيًا-  نوع معلمات الإغلاق ونوع الإرجاع ، بحيث يمكنك  إزالتها-  : -  - animals.sort { (one, two) in return one < two }
 - يمكنك استبدال أسماء المعلمات باستخدام الترميز  $ i-  : -  - animals.sort { return $0 < $1 }
 - قد لا تحتوي الإغلاقات التي تتكون من عبارة واحدة على الكلمة الأساسية  للعودة-  . تصبح قيمة العبارة الأخيرة المنفذة نتيجة الإغلاق للإغلاق: -  - animals.sort { $0 < $1 }
 - أخيرًا ، نظرًا لأن Swift يعرف أن عناصر المصفوفة تتوافق مع بروتوكول  Equatable-  ، يمكنك ببساطة كتابة: -  - animals.sort(by: <)
 - تحديث:  hummingbirddj-  المبسطة أكثر: - في هذه الحالة ، يمكنك حتى أقصر:-  -  animals.sort()
 - فرز تصاعدي ، يعمل مع الأنواع التي تنفذ للمقارنة.
 
 
 
 - السؤال 4- ينشئ هذا الرمز فئتين:  العنوان والشخص-  . كما تم إنشاء حالتين من فئة  الشخص-  (  راي وبريان-  ). -  - class Address { var fullAddress: String var city: String init(fullAddress: String, city: String) { self.fullAddress = fullAddress self.city = city } } class Person { var name: String var address: Address init(name: String, address: Address) { self.name = name self.address = address } } var headquarters = Address(fullAddress: "123 Tutorial Street", city: "Appletown") var ray = Person(name: "Ray", address: headquarters) var brian = Person(name: "Brian", address: headquarters)
 - لنفترض أن  برايان-  انتقل إلى عنوان جديد وتريد تحديث سجله على النحو التالي: -  - brian.address.fullAddress = "148 Tutorial Street"
 - هذا يجمع ويدير دون أخطاء. ولكن ، إذا قمت بالتحقق الآن من عنوان  راي-  ،  فستشاهد-  أنه  "انتقل"-  أيضًا. - ما حدث هنا وكيف يمكننا إصلاحه؟ - الجواب- العنوان فئة وله دلالات مرجعية . وبالتالي ، فإن المقر الرئيسي هو نفس مثيل الفئة التي تشترك فيها راي وبريان. سيؤدي تغيير المقر إلى تغيير عنوان كليهما.
 لإصلاح ذلك ، يمكنك إنشاء مثيل جديد لفئة العنوان وتعيينها إلى براين ، أو إعلان العنوان كبنية بدلاً من الفصل الدراسي .
 
 
 
 
 
 - أسئلة شفهية- السؤال 1- ما هو  اختياري-  وما هي المشاكل التي يحلونها؟ - الجواب- اختياري يسمح للمتغير من أي نوع بتقديم موقف " بلا قيمة ". في الهدف- C ، "لا توجد قيمة" كانت متاحة فقط في أنواع المراجع باستخدام قيمة الصفر الخاصة. أنواع القيم ، مثل int أو float ، لا تملك هذه الإمكانية.
 وسعت سويفت مفهوم "لا قيمة" لأنواع القيمة. يمكن أن يحتوي المتغير الاختياري على قيمة أو لا شيء ، مما يشير إلى عدم وجود قيمة.
 
 
 
 - السؤال 2- اذكر باختصار الاختلافات الرئيسية بين  الهيكل والطبقة-  . - الجواب- الطبقات تدعم الميراث ، ولكن الهياكل لا تدعم ذلك.
 الفئات هي نوع مرجعي ، والهياكل هي نوع قيمة.
 
 
 
 - السؤال 3- ما هي  الأدوية-  وما هي؟ - الجواب- في Swift ، يمكنك استخدام  الوراثة-  في الفصول والبنى والتعدادات. الوراثة-  إصلاح مشكلة الازدواجية رمز. إذا كان لديك طريقة تقبل المعلمات من نوع واحد ، في بعض الأحيان تضطر إلى تكرار التعليمات البرمجية للعمل مع المعلمات من نوع آخر. - على سبيل المثال ، في هذا الرمز ، تكون الوظيفة الثانية "استنساخ" للأول ، باستثناء أنه يحتوي على معلمات سلسلة ، وليس عددًا صحيحًا. -  - func areIntEqual(_ x: Int, _ y: Int) -> Bool { return x == y } func areStringsEqual(_ x: String, _ y: String) -> Bool { return x == y } areStringsEqual("ray", "ray") 
 - باستخدام الوراثة ، فإنك تجمع بين وظيفتين في واحدة وفي نفس الوقت تضمن سلامة الكتابة: -  - func areTheyEqual<T: Equatable>(_ x: T, _ y: T) -> Bool { return x == y } areTheyEqual("ray", "ray") areTheyEqual(1, 1)
 - نظرًا لأنك تختبر المساواة ، فأنت تقيد الأنواع على تلك التي تتوافق مع بروتوكول  Equatable-  . يوفر هذا الرمز النتيجة المرغوبة ويمنع نقل المعلمات من النوع الخطأ. 
 
 - السؤال 4- في بعض الحالات ، لن يكون من الممكن تجنب الاختيارات  غير المضمنة-  ضمنيًا. متى ولماذا؟ - الجواب- الأسباب الأكثر شيوعًا لاستخدام الاختيارات غير المضمنة ضمنيًا هي: - عندما لا يمكنك تهيئة خاصية ليست خالية في وقت الإنشاء. مثال نموذجي هو المنفذ في Interface Builder ، والذي تتم تهيئته دائمًا بعد مالكه. في هذه الحالة الخاصة ، إذا كان كل شيء قد تم تكوينه بشكل صحيح في Interface Builder ، فأنت مضمون في أن المنفذ غير صفري قبل استخدامه.
- لحل مشكلة حلقة المراجع القوية ، عندما تشير حالتان من الطبقات إلى بعضهما البعض وتكون الإشارة غير الصفرية إلى مثيل آخر مطلوبة. في هذه الحالة ، تقوم بوضع علامة على الرابط الموجود على جانب واحد باعتباره غير مملوك ، وعلى الجانب الآخر تستخدم توسيعًا اختياريًا ضمنيًا.
 
 
 - السؤال 5- ما هي بعض الطرق لنشر اختياري؟ معدل لهم من حيث الأمن. -  - var x : String? = "Test"
 - تلميح: فقط 7 طرق. - الجواب- إلغاء القسري-  غير آمن. -  - let a: String = x!
 النشر الضمني عند التصريح عن متغير-  غير آمن. -  - var a = x!
 الربط الاختياري-  آمن. -  - if let a = x { print("x was successfully unwrapped and is = \(a)") }
 تسلسل اختياري-  آمن. -  - let a = x?.count
 لا يوجد عامل تشغيل ائتلاف-  آمن. -  - let a = x ?? ""
 - بيان  الحرس-  آمن. -  - guard let a = x else { return }
 نمط اختياري-  - آمن. -  - if case let a? = x { print(a) }
 
 
 
 
 
 
- متوسط
 - أسئلة مكتوبة- السؤال 1- ما هو الفرق بين  لا شيء-  و. - الجواب- لا يوجد فرق ،  اختياري. بلا-  (لفترة وجيزة.  لا شيء-  ) ولا  شيء معادلان-  . - في الواقع ، سيعود العبارة التالية  صحيحاً-  : -  - nil == .none
 - استخدام  النيل غير-  مقبول بشكل عام ويوصى به. 
 
 - السؤال 2- هنا نموذج ميزان حرارة في شكل فئة وهيكل. المترجم يشكو من السطر الأخير. ما هو الخطأ هناك؟ -  - public class ThermometerClass { private(set) var temperature: Double = 0.0 public func registerTemperature(_ temperature: Double) { self.temperature = temperature } } let thermometerClass = ThermometerClass() thermometerClass.registerTemperature(56.0) public struct ThermometerStruct { private(set) var temperature: Double = 0.0 public mutating func registerTemperature(_ temperature: Double) { self.temperature = temperature } } let thermometerStruct = ThermometerStruct() thermometerStruct.registerTemperature(56.0)
 - الجواب- تم إعلان ThermometerStruct بشكل صحيح مع وظيفة متحولة لتغيير المتغير الداخلي. المترجم يشكو من أنك تقوم باستدعاء طريقة registerTemperature للمثيل الذي تم إنشاؤه باستخدام let ، لذلك هذا المثيل غير قابل للتغيير. سيؤدي تغيير السماح لـ var إلى إصلاح خطأ التحويل البرمجي.
 
 في الهياكل ، يجب عليك وضع علامة على الطرق التي تعدل المتغيرات الداخلية كتحور ، لكن لا يمكنك استدعاء هذه الطرق باستخدام مثيل ثابت.
 
 
 
 - السؤال 3- ما سوف يخرج هذا الرمز ولماذا؟ -  - var thing = "cars" let closure = { [thing] in print("I love \(thing)") } thing = "airplanes" closure()
 - الجواب- سيتم طباعتها: أنا أحب السيارات. ستقوم قائمة الالتقاط بإنشاء نسخة من المتغير عند إعلان الإغلاق. هذا يعني أن المتغير الذي تم التقاطه لن يغير قيمته ، حتى بعد تعيين قيمة جديدة. - إذا حذفت قائمة الالتقاط في الإغلاق ، فسيستخدم المترجم الرابط وليس النسخة. استدعاء الإغلاق سيعكس التغيير في المتغير: -  - var thing = "cars" let closure = { print("I love \(thing)") } thing = "airplanes" closure() 
 
 
 - السؤال 4- هذه دالة تحسب عدد القيم الفريدة في صفيف: -  - func countUniques<T: Comparable>(_ array: Array<T>) -> Int { let sorted = array.sorted() let initial: (T?, Int) = (.none, 0) let reduced = sorted.reduce(initial) { ($1, $0.0 == $1 ? $0.1 : $0.1 + 1) } return reduced.1 }
 - يستخدم الفرز ، لذلك يستخدم فقط الأنواع التي تتوافق مع البروتوكول المقارن. - يمكنك تسميتها مثل هذا: -  - countUniques([1, 2, 3, 3]) 
 - أعد كتابة هذه الوظيفة كملحق Array بحيث يمكنك استخدامها مثل هذا: -  - [1, 2, 3, 3].countUniques() 
 - ملاحظة المترجم- شيء مؤلم للغاية هو وظيفة وحشية. لماذا لا: -  - func countUniques<T: Hashable>(_ array: Array<T>) -> Int { return Set(array).count }
 
 - الجواب-  - extension Array where Element: Comparable { func countUniques() -> Int { let sortedValues = sorted() let initial: (Element?, Int) = (.none, 0) let reduced = sortedValues.reduce(initial) { ($1, $0.0 == $1 ? $0.1 : $0.1 + 1) } return reduced.1 } }
 
 
 - السؤال 5- هذه دالة تقسم الزوجين الاختياريين. هناك ثلاثة شروط يجب الوفاء بها: - لا ينبغي أن يكون الربح لا شيء
- يجب أن لا يكون المقسوم صفراً
- يجب ألا يكون المقسوم على 0
 -  - func divide(_ dividend: Double?, by divisor: Double?) -> Double? { if dividend == nil { return nil } if divisor == nil { return nil } if divisor == 0 { return nil } return dividend! / divisor! }
 - أعد كتابة هذه الوظيفة باستخدام بيان  الحماية-  وعدم استخدام الضغط القسري. - الجواب- يوفر بيان  الحماية-  الذي تم تقديمه في Swift 2.0 خروجًا إذا لم يتم الوفاء بالشرط. هنا مثال: -  - guard dividend != nil else { return nil }
 - يمكنك أيضًا استخدام بيان الحماية  للربط الاختياري-  ، وبعد ذلك سيتوفر المتغير الموسع  خارج بيان الحماية-  : -  - guard let dividend = dividend else { return .none }
 - حتى تتمكن من إعادة كتابة الوظيفة مثل هذا: -  - func divide(_ dividend: Double?, by divisor: Double?) -> Double? { guard let dividend = dividend else { return nil } guard let divisor = divisor else { return nil } guard divisor != 0 else { return nil } return dividend / divisor }
 - لاحظ عدم وجود تفريغ قسري ، نظرًا لأننا قمنا بالفعل بتفريغ العائد والمقسوم عليه ووضعه في متغيرات ثابتة غير اختيارية. - لاحظ أيضًا أن نتيجة الاختيارات غير المعبأة في بيان الحماية متاحة أيضًا خارج بيان الحماية. - يمكنك تبسيط الوظيفة من خلال تجميع بيانات الحماية: -  - func divide(_ dividend: Double?, by divisor: Double?) -> Double? { guard let dividend = dividend, let divisor = divisor, divisor != 0 else { return nil } return dividend / divisor }
 
 
 - السؤال 6- أعد كتابة الطريقة من السؤال 5 باستخدام عبارة  if let-  . - الجواب- تسمح لك عبارة if let بإلغاء تحميل الخيارات الاختيارية واستخدام هذه القيمة داخل مجموعة التعليمات البرمجية هذه. خارجها ، هذه القيم لن تكون متاحة. -  - func divide(_ dividend: Double?, by divisor: Double?) -> Double? { if let dividend = dividend, let divisor = divisor, divisor != 0 { return dividend / divisor } else { return nil } }
 
 
 
 
 - أسئلة شفهية- السؤال 1- في Objective-C ، تعلن ثابت مثل هذا: -  - const int number = 0;
 - وهكذا في سويفت: -  - let number = 0
 - ما هو الفرق؟ - الجواب- في  Objective-C ،-  تتم تهيئة ثابت  في وقت الترجمة مع-  قيمة يجب أن تكون معروفة في هذه المرحلة. - القيمة الثابتة التي تم إنشاؤها باستخدام  let-  هي قيمة ثابتة محددة  في وقت التشغيل-  . يمكنك تهيئته بتعبير ثابت أو ديناميكي. لذلك ، يمكننا أن نفعل هذا: -  - let higherNumber = number + 5
 - يرجى ملاحظة أن هذه المهمة لا يمكن القيام بها إلا مرة واحدة. 
 
 - السؤال 2- لإعلان خاصية ثابتة أو دالة لأنواع القيمة ، يتم استخدام المعدل  الثابت-  . فيما يلي مثال للبنية: -  - struct Sun { static func illuminate() {} }
 - وبالنسبة للفئات ، من الممكن استخدام المعدلات  الثابتة-  أو المعدلات  الصفية-  . النتيجة هي نفسها ، ولكن هناك فرق. صفها. - الجواب- ثابت-  يجعل خاصية أو وظيفة ثابتة  وغير متداخلة-  . باستخدام فئة  سوف تتجاوز-  خاصية أو وظيفة. - هنا سوف يقسم المترجم في محاولة لتجاوز  illuminate ()-  : -  - class Star { class func spin() {} static func illuminate() {} } class Sun : Star { override class func spin() { super.spin() } 
 
 
 
 - السؤال 3- هل من الممكن إضافة  خاصية مخزنة-  إلى نوع باستخدام  ملحق-  ؟ كيف أم لا؟ - الجواب- لا ، هذا غير ممكن. يمكننا استخدام الإضافة لإضافة سلوك جديد إلى نوع موجود ، لكن لا يمكننا تغيير النوع نفسه أو واجهته. لتخزين الخاصية المخزنة الجديدة ، نحتاج إلى ذاكرة إضافية ، ولا يمكن للإضافة القيام بذلك.
 
 
 
 - السؤال 4- ما هو البروتوكول في سويفت؟ - الجواب- البروتوكول هو نوع يحدد الخطوط العريضة للطرق ، الخصائص ، إلخ. يمكن للفئة أو البنية أو التعداد أخذ بروتوكول لتنفيذ كل هذا. لا يقوم البروتوكول نفسه بتنفيذ الوظيفة ، ولكنه يعرّفها.
 
 
 
 
 
 
- متقدم
 - أسئلة مكتوبة- السؤال 1- لنفترض أن لدينا هيكلًا يحدد نموذج مقياس الحرارة: -  - public struct Thermometer { public var temperature: Double public init(temperature: Double) { self.temperature = temperature } }
 - لإنشاء مثيل ، نكتب: -  - var t: Thermometer = Thermometer(temperature:56.8)
 - ولكن شيء مثل هذا سيكون أكثر ملاءمة: -  - var thermometer: Thermometer = 56.8
 - هل هذا ممكن؟ كيف؟ - الجواب- يحدد Swift البروتوكولات التي تسمح لك بتهيئة نوع باستخدام القيم الحرفية حسب الواجب. سيسمح تطبيق البروتوكول المناسب وتوفير مُهيئ عام للتهيئة باستخدام القيم الحرفية. في حالة مقياس الحرارة ، ننفذ  ExpressibleByFloatLiteral-  : -  - extension Thermometer: ExpressibleByFloatLiteral { public init(floatLiteral value: FloatLiteralType) { self.init(temperature: value) } }
 - الآن يمكننا إنشاء مثيل مثل هذا: -  - var thermometer: Thermometer = 56.8
 
 
 - السؤال 2- يحتوي Swift على مجموعة من العوامل المحددة مسبقًا للعمليات الحسابية والمنطقية. كما يسمح لك بإنشاء مشغلي الخاصة بك ، سواء أحادي وثنائي. - قم بتحديد وتنفيذ مشغل الأس الخاص بك (^^) وفقًا للمتطلبات التالية: - يأخذ اثنين من كثافة العمليات كمعلمات
- إرجاع نتيجة رفع المعلمة الأولى إلى قوة الثانية
- يعالج بشكل صحيح ترتيب العمليات الجبرية
- يتجاهل أخطاء تجاوز السعة المحتملة
 - الجواب- يتم إنشاء مشغل جديد على مرحلتين: الإعلان والتنفيذ. - يستخدم الإعلان الكلمة الأساسية  للمشغل-  لتحديد النوع (أحادي أو ثنائي) ، لتحديد تسلسل أحرف المشغل الجديد ، ورابطيته وأسبقية التنفيذ. - المشغل هنا هو ^ ^ ونوعه هو infix (ثنائي). الارتباط هو الصحيح. - لا يحتوي سويفت على الأقدمية المحددة مسبقًا للتسوية. في الجبر ، يجب حساب الأس قبل الضرب / القسمة. وبالتالي ، نقوم بإنشاء أمر تنفيذ مخصص عن طريق وضع الأس على أعلى من الضرب. - هذا الإعلان: -  - precedencegroup ExponentPrecedence { higherThan: MultiplicationPrecedence associativity: right } infix operator ^^: ExponentPrecedence
 - هذا هو التنفيذ: -  - func ^^(base: Int, exponent: Int) -> Int { let l = Double(base) let r = Double(exponent) let p = pow(l, r) return Int(p) }
 
 
 - السؤال 3- تعرّف التعليمة البرمجية التالية بنية  بيتزا-  وبروتوكول  بيتزا-  بملحق للتطبيق الافتراضي  لطريقة makeMargherita ()-  : -  - struct Pizza { let ingredients: [String] } protocol Pizzeria { func makePizza(_ ingredients: [String]) -> Pizza func makeMargherita() -> Pizza } extension Pizzeria { func makeMargherita() -> Pizza { return makePizza(["tomato", "mozzarella"]) } }
 - الآن نحدد مطعم  لومبارديس-  : -  - struct Lombardis: Pizzeria { func makePizza(_ ingredients: [String]) -> Pizza { return Pizza(ingredients: ingredients) } func makeMargherita() -> Pizza { return makePizza(["tomato", "basil", "mozzarella"]) } }
 - ينشئ التعليمة البرمجية التالية مثيلين من  Lombardis-  . أي منهم يصنع المارجريتا بالريحان؟ -  - let lombardis1: Pizzeria = Lombardis() let lombardis2: Lombardis = Lombardis() lombardis1.makeMargherita() lombardis2.makeMargherita()
 - الجواب- في كليهما. يعلن بروتوكول  Pizzeria-  طريقة  makeMargherita ()-  ويوفر تطبيقًا افتراضيًا. يتجاوز تطبيق  Lombardis-  الطريقة الافتراضية. نظرًا لأننا أعلنا الطريقة في البروتوكول في مكانين ، فسيتم استدعاء التطبيق الصحيح. - ولكن ماذا لو لم يعلن  البروتوكول-  طريقة  makeMargherita ()-  ، ولا يزال التمديد يوفر التنفيذ الافتراضي ، مثل هذا: -  - protocol Pizzeria { func makePizza(_ ingredients: [String]) -> Pizza } extension Pizzeria { func makeMargherita() -> Pizza { return makePizza(["tomato", "mozzarella"]) } }
 - في هذه الحالة ، سيكون فقط lombardis2 البيتزا مع الريحان ، بينما lombardis1 لن يكون لديه بيتزا ، لأنه سيستخدم الطريقة المحددة في التمديد. 
 
 - السؤال 4- لا يتم ترجمة التعليمات البرمجية التالية. هل يمكنك شرح ما هو الخطأ معه؟ اقترح حلول للمشكلة. -  - struct Kitten { } func showKitten(kitten: Kitten?) { guard let k = kitten else { print("There is no kitten") } print(k) }
 - تلميح: هناك ثلاث طرق لإصلاح الخطأ. - الجواب- تتطلب الكتلة  الأخرى-  من بيان  الحماية-  خيار الخروج ، إما باستخدام  الإرجاع-  أو الاستثناء أو الاتصال على  noreturn-  . الحل الأبسط هو إضافة  بيان الإرجاع-  . -  - func showKitten(kitten: Kitten?) { guard let k = kitten else { print("There is no kitten") return } print(k) }
 - هذا الحل سوف يلقي استثناء: -  - enum KittenError: Error { case NoKitten } struct Kitten { } func showKitten(kitten: Kitten?) throws { guard let k = kitten else { print("There is no kitten") throw KittenError.NoKitten } print(k) } try showKitten(kitten: nil)
 - أخيرًا ،  ها-  هي استدعاء  fatalError ()-  ، وظيفة  @ noreturn-  . -  - struct Kitten { } func showKitten(kitten: Kitten?) { guard let k = kitten else { print("There is no kitten") fatalError() } print(k) }
 
 
 
 
 - أسئلة شفهية- السؤال 1- هل عمليات الإغلاق هي نوع المرجع أو نوع القيمة؟ - الجواب- الإغلاقات هي نوع مرجعي. إذا قمت بتعيين إغلاق لمتغير ثم قمت بنسخه إلى متغير آخر ، فإنك تنسخ الرابط إلى نفس الإغلاق وقائمة الالتقاط الخاصة به.
 
 
 
 - السؤال 2- يمكنك استخدام نوع  UInt-  لتخزين عدد صحيح غير موقعة. ينفذ مُهيئ للتحويل من علامة برمجية: -  - init(_ value: Int)
 - ومع ذلك ، لا يتم ترجمة التعليمات البرمجية التالية إذا حددت قيمة سالبة: -  - let myNegative = UInt(-1)
 - أعداد صحيحة موقعة ، بحكم التعريف ، لا يمكن أن تكون سالبة. ومع ذلك ، من الممكن استخدام تمثيل رقم سالب في الذاكرة لترجمته إلى رقم غير موقع. - كيف يمكنني تحويل عدد صحيح سالب إلى UInt مع الحفاظ على تمثيله في الذاكرة؟ - الجواب- يوجد مُهيئ لهذا: -  - UInt(bitPattern: Int)
 - واستخدام: -  - let myNegative = UInt(bitPattern: -1)
 
 
 - السؤال 3- وصف المراجع الدائرية في سويفت؟ كيف يمكن أن تكون ثابتة؟ - الجواب- تحدث المراجع الدائرية عندما تحتوي حالتان على مرجع قوي لبعضهما البعض ، مما يؤدي إلى تسرب للذاكرة بسبب عدم إمكانية تحرير أي من هذه الحالات. لا يمكن تحرير مثيل بينما لا تزال هناك إشارات قوية إليه ، ولكن هناك مثيل واحد يحمل الآخر.
 
 يمكن حل ذلك عن طريق استبدال الرابط على جانب واحد عن طريق تحديد الكلمة الرئيسية ضعيفة أو غير مملوكة .
 
 
 
 - السؤال 4- يسمح لك Swift بإنشاء تعدادات متكررة. فيما يلي مثال على هذا التعداد الذي يحتوي على متغير Node مع نوعين من الجمعيات ، T و List: -  - enum List<T> { case node(T, List<T>) }
 - سيكون هناك خطأ في الترجمة. ماذا افتقدنا؟ - الجواب- لقد نسينا الكلمة الرئيسية  غير المباشرة-  ، والتي تتيح خيارات التعداد العودية المماثلة: -  - enum List<T> { indirect case node(T, List<T>) }