مرحبا اسمي ايليا. أنا مطور دائرة الرقابة الداخلية في Tinkoff.ru. في هذه المقالة ، سأقدم نظرة عامة مختصرة على التغييرات الرئيسية في Swift 5. هذه التغييرات موصوفة في
ملاحظات الإصدار . بالنسبة لأولئك الذين لم تتعرف على نفسك بعد ، مرحبًا بكم في cat!

سوف ينخفض حجم التطبيق!
لن تتضمن التطبيقات المكتوبة بلغة Swift 5 والتي تم تجميعها لنظام التشغيل iOS 12.2 و watchOS 5.2 و tvOS 12.2 مكتبات ديناميكية لمكتبة Swift القياسية و Swift SDK. وهذا يعني أن حجم التطبيق سينخفض ، ولكن ليس كثيرًا. إذا كنت تعتقد أن
هذه التغريدة ، فقد تم تقليل حجم المشروع الفارغ من 2.4 ميغابايت إلى 24 كيلوبايت. نتيجة جيدة للتطبيقات الصغيرة ، ولكن بالنسبة للتطبيقات الكبيرة لن يكون هناك فرق كبير.
dynamicCallable ( SE-0216 )
تسمح
لك السمة
dynamicCallable بالعمل مع كائن كدالة. تسمى هذه الكائنات كائنات وظيفية أو عوامل توجيه (يمكن العثور على مزيد من التفاصيل
هنا ). الكائنات الوظيفية هي في لغة C ++ و Python و JavaScript ولغات أخرى ، وفي لغة سويفت تمت إضافتها للتوافق مع هذه اللغات. الحقيقة هي أن Swift يتفاعل الآن بشكل جيد مع API C و Objective-C ، ويريد مطورو اللغة إضافة التفاعل مع اللغات الديناميكية - Python و JavaScript و Ruby وغيرها.
من أجل جعل الكتابة مُشغّلاً ، يجب إضافة السمة
@ dynamicCallable إلى الإعلان الخاص بها. النظر في مثال على هيكل
المخفض الذي يمكن استخدامه لإضافة أرقام في صفيف:
@dynamicCallable struct Reducer { ... }
ثم تحتاج إلى تنفيذ أحد الأساليب التالية أو كليهما:
func dynamicallyCall(withArguments: ExpressibleByArrayLiteral) func dynamicallyCall(withKeywordArguments: ExpressibleByDictionaryLiteral)
تتيح لك الوظيفة الأولى الوصول إلى الكائن عن طريق تمرير صفيف كوسائط. تتيح لك الوظيفة الثانية الوصول إلى الكائن ، بتمرير نفس الصفيف مثل الوسائط ، ولكن باستخدام أسماء الوسائط.
على سبيل المثال ، يبدو تنفيذ الوظيفة الأولى لهيكل
المخفض كما يلي:
func dynamicallyCall(withArguments arguments: [Int]) -> Int { return arguments.reduce(0, +) }
ثم تطبيق مثل هذا الهيكل على النحو التالي:
let reducer = Reducer() let sum = reducer(1, 2, 3)
سننظر في تنفيذ الطريقة الثانية باستخدام مثال بنية
المقارنة ، والذي يمكننا من خلاله مقارنة رقمين:
@dynamicCallable struct Comparator { func dynamicallyCall(withKeywordArguments arguments: KeValuePairs<String, Int>) -> ComparisonResult { guard let lhs = arguments["lhs"], let rhs = arguments["rhs"], lhs != rhs else { return .orderedSame } return lhs > rhs ? .orderedDescending : .orderedAscending } }
يمكنك استخدام هذا الهيكل على النحو التالي:
let comparator = Comparator() let comparisionResult = comparator(lhs: 1, rhs: 2)
يعلم الكثير من الناس أنه عند معالجة قيم التعداد ، من الضروري وصف جميع الحالات ومحاولة عدم استخدام الإعداد الافتراضي. على الرغم من أن هذا المطلب يضيف القليل من الأمان ، إلا أنه يحتوي أيضًا على عيب ، لأنه عند تغيير القيم في التعداد ، تحتاج إلى إضافة معالجتها. لا تزال هناك فرصة لتغيير إطار النظام بعض التعدادات ، لكن لم تتم معالجة ذلك في التطبيق الخاص بك (لذلك ، على سبيل المثال ، كان مع
LABiometryType ).
سيضيف Swift 5 السمة
غير المعروفة ، مما سيتيح لك فصل سيناريوهين مختلفين عند معالجة التعداد:
- يجب تنفيذ التعليمات البرمجية الافتراضية في جميع الحالات التي لم تتم معالجتها بتبديل
- تتم معالجة جميع الحالات في التبديل ، وإذا تمت إضافة حالات جديدة ، فأنت بحاجة إلى استخدام الرمز بشكل افتراضي
لنلقِ نظرة على مثال:
enum HTTPMethod { case post, get, put }
التخلص من ضعف اختياري نتيجة لاستدعاء وظيفة مع محاولة؟ ( SE-0230 )
بالتأكيد صادف الكثيرون حقيقة أنه عند استدعاء وظيفة رمي ، والتي تعود
اختياري ، باستخدام
محاولة؟ ، والنتيجة هي نوع ملفوف في اثنين
اختياري . هذه ليست مريحة للغاية ، وحتى في سويفت 5 ، اتصل
محاولة؟ في هذه الحالة سيعود نوع ملفوف في واحد
اختياري فقط.
هكذا كان الحال قبل Swift 5:
let result = try? optionalObject?.foo()
وهكذا سيكون في Swift 5:
let result = try? optionalObject?.foo()
تحقق التعددية ( SE-0225 )
للتحقق من تعدد رقم لآخر ، يمكنك استخدام
isMultiple (of :) ، بدلاً من باقي القسمة (٪):
التغيير بسيط ، لكنه يجعل الكود أكثر وضوحًا ويبسط عملية البحث عن طريق الكود.
حساب عدد العناصر في تسلسل مع شرط ( SE-0220 )
في Swift 5 ، سيضيف نوع التسلسل
العد (حيث: (العنصر) -> Bool) -> طريقة ، والتي سوف تتيح لك حساب عدد العناصر في تسلسل تفي بشرط معين في مرور واحد. قبل ذلك ، اضطررت إلى استخدام
مرشح بالتزامن مع
العد . ستوفر هذه الطريقة الذاكرة المخصصة عند إنشاء صفيف جديد في طريقة
التصفية .
مثال:
let countOfZeroes = [0, 1, 2, 0, 4].count(where: { $0 == 0 })
طريقة CompactMapValues في القاموس ( SE-0218 )
هذه الطريقة تجمع بين
compMap من
Array و
mapValues من
القاموس . نتيجة لاستدعاء هذه الطريقة ، يتم إنشاء قاموس ذو قيم محولة لا توجد فيه قيم تساوي
الصفر .
مثال:
let dictionary = ["a": "1", "b": "2", "c": "Number"] let resultDictionary = dictionary.compactMapValues { Int($0) }
أضيفت القدرة على كتابة السطور التي تستخدم فيها علامات الاقتباس و الشرطة المائلة للخلف كأحرف عادية ، وليس كأحرف خاصة. للقيام بذلك ، أضف الحرف # في بداية ونهاية السطر.
مثال:
let string1 = #" " ""# let string2 = #" \ "#
إذا كنت تقوم بإدخال متغير عند إنشاء خط ، فأنت بحاجة إلى إضافة علامة # بعد:
let string = #" \#(variable)"#
إذا كان للخط علامة # ، فأنت بحاجة إلى إضافة علامتي ## في بداية ونهاية السطر:
let string = ##" #"##
بروتوكول التسلسل لم يعد يحتوي على النوع المقترن SubSequence ( SE-0234 )
تم نقل النوع
الترابطي من
SubSequence من بروتوكول
Sequence إلى
Collection ، والآن ترجع جميع الأساليب في
Sequence التي أعادت
SubSequence نوعًا معينًا. على سبيل المثال ، تقوم الطريقة
اللاحقة الآن بإرجاع
صفيف . فيما يلي قائمة كاملة بالطرق التي تأثرت بهذا التغيير:
extension Sequence { public func dropFirst(_ k: Int = 1) -> DropFirstSequence<Self> public func dropLast(_ k: Int = 1) -> [Element] public func suffix(_ maxLength: Int) -> [Element] public func prefix(_ maxLength: Int) -> PrefixSequence<Self> public func drop(while predicate: (Element) throws -> Bool) rethrows -> DropWhileSequence<Self> public func prefix(while predicate: (Element) throws -> Bool) rethrows -> [Element] public func split( maxSplits: Int = Int.max, omittingEmptySubsequences: Bool = true, whereSeparator isSeparator: (Element) throws -> Bool ) rethrows -> [ArraySlice<Element>] }
الآن العمل مع هذه الأساليب سوف تصبح أسهل.
قيود البروتوكول
تدعم البروتوكولات الآن التقييد في شكل فئات تنفذ هذا البروتوكول. بمعنى آخر ، يمكنك الآن الإشارة إلى أنه لا يمكن تنفيذ البروتوكول إلا من خلال فئة معينة. على سبيل المثال:
protocol Viewable: UIView {} protocol Viewable where Self: UIView {}
يتم دعم خيار التسجيل الثاني في Swift 4.2 ، ولكنه قد يتسبب في حدوث خطأ في الترجمة أو وقت التشغيل. في Swift 5 ، لن يحدث هذا الخطأ.
الخاتمة
هذه ليست قائمة كاملة بالتغييرات في Swift 5 ؛ حيث يتم جمع التغييرات الرئيسية فقط هنا. بشكل عام ، تكون التغييرات المقدمة إيجابية وتجعل اللغة أكثر قابلية للفهم ومرونة. الشيء الرئيسي هو أن "تحويل إلى صيغة سويفت الحالية" يجب أن تكون غير مؤلمة.
هذا كل شيء ، شكرا للقراءة.