سويفت 5.0. ما الجديد؟

Swift 5 - الإصدار الذي طال انتظاره ، والذي يتضمن عشرات التحسينات والإصلاحات. لكن الهدف الرئيسي لإطلاق Swift 5.0 كان تحقيق استقرار ABI. في هذه المقالة ، سوف تتعرف على ماهية ABI وماهية ABI الثابتة التي ستوفر لمطوري iOS / macOS. سنقوم أيضًا بتحليل العديد من الميزات الجديدة لـ Swift 5.



أبي الاستقرار


ABI هي واجهة تطبيق ثنائية. يمكن اعتبار ABI كمجموعة من القواعد التي تسمح للرابط بدمج وحدات المكون المترجمة.


وفقا لذلك ، تم وصف ما يلي في ABI.


  1. يتم استدعاء رمز الطريق من وحدات مختلفة ، بما في ذلك وحدات النظام.
  2. تنسيق تمرير الوسائط والحصول على قيمة الإرجاع من الدالات.
  3. خوارزميات تخطيط بيانات RAM.
  4. إدارة الذاكرة ، ARC.
  5. اكتب نظام ، الوراثة.

يوفر Swift 5 ، إلى جانب ABI المستقر ، توافقًا ثنائيًا للتطبيقات. يعني التوافق الثنائي لتطبيقات iOS / macOS أن التطبيقات المترجمة ستكون متوافقة في وقت التشغيل مع مكتبات النظام المترجمة بواسطة إصدارات سابقة أو أحدث من اللغة. على سبيل المثال ، سيتوافق تطبيق مترجم مع Swift 5.0 مع المكتبات القياسية المترجمة مع Swift 5.1 أو Swift 6.0.


بدءًا من iOS 12.2 و macOS 10.14.4 ، ستحتوي أنظمة تشغيل Apple على كل ما تحتاجه لتشغيل التطبيقات السريعة. هذا يعني أن التطبيقات المكتوبة في Swift 5 والإصدارات الأحدث لن تحتوي على وقت تشغيل ومكتبة لغة قياسية. لذلك ، سوف تزن التطبيقات المكتوبة في Swift 5 حوالي 3-10 ميغابايت.


من المهم ملاحظة أنه بالإضافة إلى ثبات ABI ، هناك أيضًا ثبات الوحدة. إذا كان استقرار ABI يسمح بدمج إصدارات مختلفة من سرعة في وقت التشغيل ، فإن استقرار الوحدة النمطية هو المسؤول عن كيفية تجميع الأطر الثنائية المكتوبة في إصدارات مختلفة من اللغة. ستظهر وحدة الاستقرار في Swift 5.1. وبعد ذلك ، سيتمكن المطورون من توزيع أطر عملهم ، ليس فقط باستخدام شفرة المصدر المفتوح ، ولكن أيضًا في شكل مترجم.


إيجابيات الاستقرار ABI.


  1. التطبيقات سوف تزن أقل.
  2. تسريع بدء التشغيل وأداء التطبيق.
  3. من الناحية النظرية ، يمكن أن أبل كتابة أطر جديدة تماما على سويفت.

سلبيات أبي الاستقرار.


سيتعين على المطورين مراعاة عدم وجود أي وظائف جديدة في الإصدارات القديمة من المكتبة القياسية. على سبيل المثال ، إذا تم إنشاء Swift 5.1 مع أي فئات / وظائف جديدة في المكتبة القياسية في iOS 13 ، ثم مع الدعم في تطبيق iOS 12.2 ، فلن يتمكن مطورو البرامج من استخدامها. (ستحتاج إلى إدراج #available (...) الاختبارات بنفس الطريقة التي نستخدمها الآن مع مكتبات Foundation و UIKit وغيرها من مكتبات الأنظمة الأساسية).


نوع النتيجة في المكتبة القياسية


تحتوي المكتبة القياسية على طريقة ملائمة لنقل الأخطاء ومعالجتها في واجهة برمجة التطبيقات غير المتزامنة. يمكنك أيضًا استخدام هذا النوع إذا كانت معالجة الأخطاء القياسية من خلال try / catch لسبب ما لا تناسبنا.


يتم تنفيذ نوع النتيجة من خلال التعداد مع حالتين: النجاح والفشل:


public enum Result<Success, Failure> where Failure: Error { case success(Success) case failure(Failure) ... } 

في الواقع ، هذا النهج ليس جديدا على مطوري سويفت. منذ الإصدار الأول من Swift ، استخدم العديد من المطورين طريقة مماثلة. ولكن الآن ، عندما تظهر النتيجة في المكتبة القياسية ، سيؤدي ذلك إلى تبسيط التفاعل مع التعليمات البرمجية من المكتبات الخارجية.


مثال على استخدام خدمة تنزيل المقالة:


 struct Article { let title: String } class ArticleService { func fetchArticle(id: Int64, completion: @escaping (Result<Article, Error>) -> Void) { //    // ... completion(.success(Article(title: "Swift 5.0.  ?"))) } } 

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


 articleService.fetchArticle(id: 42) { result in switch result { case .success(let article): print("Success: \(article)") case .failure(let error): print("Failure: \(error)") } } 

سلاسل الخام


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


مثال على استخدام علامات الاقتباس:


 // swift 4.2 print("    \"\"   .") print("     ,    \\n") // swift 5 print(#" ""      "#) print(#"     ,    \n"#) 

هذه الميزة مفيدة بشكل خاص عند كتابة التعبيرات العادية:


 // swift 4.2 let regex = "^\\(*\\d{3}\\)*( |-)*\\d{3}( |-)*\\d{4}$" // swift 5 let regex = #"^\(*\d{3}\)*( |-)*\d{3}( |-)*\d{4}$"# 

لمرافقة الأسطر بعد الشرطة المائلة للخلف ، أضف الحرف #:


 // swift 4.2 let string = "   \(variable)" // swift 5 let string = #"   \#(variable)"# 

يمكنك قراءة المزيد في هذه الجملة .


تحديث خط الاستيفاء


باستخدام استيفاء السلسلة ، يمكننا إضافة قيمة المتغير أو نتيجة تعبير إلى حرفية السلسلة. بدءًا من الإصدار الخامس من اللغة ، أصبح من الممكن توسيع طريقة إضافة تعبيراتنا إلى السطر الأخير.
بشكل عام ، ما عليك سوى كتابة ملحق إلى بنية DefaultStringInterpolation وإضافة طريقة تسمى appendInterpolation. على سبيل المثال ، إذا أردنا إضافة سعر في شكل منسق إلى سلسلة:


 extension DefaultStringInterpolation { mutating func appendInterpolation(price: Decimal) { let formatter = NumberFormatter() formatter.numberStyle = .currency if let string = formatter.string(from: price as NSDecimalNumber) { appendLiteral(string) } else { appendLiteral(price.description) } } } print("Price of item: \(price: 9.99)") // Price of item: $9.99 

من المهم ملاحظة أنه في الواقع ، تم تحويل الإنشاء (السعر: 9.99) في سلسلة باستخدام المترجم إلى استدعاء الأسلوب appendInterpolation (السعر: العشري).
أيضًا في أساليب appendInterpolation ، يمكننا إضافة عدد غير محدود من الوسائط ، سواء كانت مسماة أو غير مسماة ، بقيم افتراضية أو بدونها.


يمكنك قراءة المزيد في هذه الجملة .


التحقق من تعدد الأرقام


تم إضافة طريقة التحقق من التعدد isMultiple (of :) إلى الأنواع الرقمية في المكتبة القياسية. نعم ، لا يزال بإمكاننا استخدام المشغل لأخذ الجزء المتبقي من القسمة٪. ولكن يبدو أن isMultiple (من :) يبدو أكثر مرئية.


 let interger = 42 if interger.isMultiple(of: 3) { print(" ") } else { print("  ") } 

طريقة CompactMapValues ​​في القاموس


تسمح لك طريقة compMapValues ​​بتحويل قيم القاموس ، وكذلك ترشيحها في حالة إرجاع التحويل نفسه إلى الصفر.


على سبيل المثال ، تعيين مفاتيح السلسلة لنوع URL:


 let dict = [ "site": "https://www.site.ru/path/to/web/site/page", "other site": "invalid url" ] let mappedDict: [String: URL] = dict.compactMapValues { URL(string: $0) } print(mappedDict) // ["site": https://www.site.ru/path/to/web/site/page] 

تم حذف زوج المفتاح / القيمة الثاني بعد التعيين ، لأن السلسلة ليست عنوان URL صالحًا.


حاول تغيير السلوك؟


في سويفت 4.2 باستخدام محاولة بناء؟ يمكنك بسهولة الحصول على نوع اختياري مع عدة مستويات من التعشيش. في معظم الحالات ، ليس هذا ما يتوقعه المطور. لهذا السبب ، في سويفت 5 جرب؟ حصلت على سلوك مماثل لسلسلة ج اختياري. هذا هو ، مع مزيج من المحاولة؟ مع تسلسل اختياري أو صب اختياري ، ستكون نتيجة التعبير اختيارية بمستوى واحد من التعشيش.


جرب المثال؟ جنبا إلى جنب مع كما؟


 // Swift 4.2 let jsonDict = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] //  jsonDict - [String: Any]?? // Swift 5 let jsonDict = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] //  jsonDict - [String: Any]? 

جرب المثال؟ مع طريقة الكائن الاختيارية:


 // Swift 4.2 let article = try? storage?.getArticle() //  article - Article?? //  if let first = article, let second = first { first //  Article? second //  Article } //   if case let value?? = article { value //  Article } // Swift 5 let article = try? storage?.getArticle() //  article - Article? //  if let value = article { value //  Article } 

يمكنك قراءة المزيد في هذه الجملة .


DynamicCallable السمة


تسمح لك السمة الجديدةdynamicCallable بتمييز النوع على أنه "callable". هذا يعني أنه يمكننا استدعاء النوع كطريقة عادية.
إذا وضعنا علامة على النوع على أنهdynamicCallable ، فيجب علينا تطبيق إحدى الطرق (أو كليهما):


 func dynamicallyCall(withArguments: <#Arguments#>) -> <#R1#> func dynamicallyCall(withKeywordArguments: <#KeywordArguments#>) -> <#R2#> 

يجب أن يدعم نوع الوسائط بروتوكول ExpressibleByArrayLiteral ، ويجب أن يدعم نوع KeywordArguments بروتوكول ExpressibleByDictionaryLiteral ، ويمكن أن يكون R1 و R2 أي أنواع.


على سبيل المثال ، هيكل سوم. عند الاتصال به ، يمكنك نقل أي عدد من الأرقام والحصول على مجموعها:


 @dynamicCallable struct Sum { func dynamicallyCall(withArguments args: [Int]) -> Int { return args.reduce(0, +) } } let sum = Sum() let result = sum(1, 2, 3, 4) print(result) // 10 

في الواقع ، يقوم المحول البرمجي بتحويل المبلغ (1 ، 2 ، 3 ، 4) إلى استدعاء sum.dynamicallyCall (withArguments: [1، 2، 3، 4]). وبالمثل بالنسبة إلى dynamicallyCall (withKeywordArguments :) الأسلوب.


تتيح لك هذه الميزة إضافة تفاعل كود Swift مع لغات البرمجة الديناميكية المختلفة ، على سبيل المثال ، Python أو JavaScript.


يمكنك قراءة المزيد في هذه الجملة .


دعم مشغل أقل في إصدار برنامج التحويل البرمجي وتوجيهات التحقق من اللغة


بدءًا من الإصدار الخامس من Swift ، يمكنك استخدام عامل التشغيل "الأقل" عند التحقق من إصدار برنامج التحويل البرمجي في الكود:


 // Swift 4.2 #if !swift(>=5) //        4.2   #endif // Swift 5 #if swift(<5) //        4.2   #endif 

استنتاج


هذه ليست جميع الميزات والتحسينات التي ظهرت في Swift 5. في المجموع ، تم قبول 28 اقتراحًا من المجتمع ، والتي تضمنت أيضًا تحسين أداء الخطوط وتحسين Swift Package Manager والمكتبة القياسية. يمكن العثور على قائمة كاملة من التغييرات والتحسينات في ملاحظات الإصدار .

Source: https://habr.com/ru/post/ar444862/


All Articles