في نهاية مارس ، تم إصدار Swift 5.2 لـ Xcode 11.4. لقد قامت بتحسين تشخيص الأخطاء وتحليل التبعية وتوسيع وظائف SwiftPM. تم بالفعل نشر نظرة عامة على بعض التغييرات على حبري ، في نفس المقالة ، تم النظر في تطور اللغة نفسها مع أمثلة محتملة للاستخدام.
يضع الاختصار keyPath في دالة ، حيث تكون معلمة الإدخال هي الكائن نفسه ، والنتيجة هي خاصيتها.لنلقي نظرة على مثال. إنشاء مجموعة من النماذج البسيطة:struct Model {
let isHidden: Bool
}
let modelArray = [Model(isHidden: true), Model(isHidden: false)]
تصفية الصفيف بواسطة الخاصية isHidden. فيما يلي 3 أمثلة لها نفس النتيجة:
let funcIsHidden: (Model) -> Bool = \.isHidden
modelArray.filter(funcIsHidden)
modelArray.filter(\.isHidden as (Model) -> Bool)
modelArray.filter(\.isHidden)
لا تعمل الوظيفة المعلنة في المثال التالي:
let selfFunc: (Model) -> Model = \.self
modelArray.compactMap(selfFunc)
modelArray.compactMap(\.self as (Model) -> Model)
modelArray.compactMap(\.self)
أيضًا ، على عكس keyPath ، لا يعمل الإكمال التلقائي.إنه مناسب للاستخدام مع المصفوفات في وظائف مثل التصفية ، والخريطة ، والتصغير ، والفرز ، وما شابه.قد تحتوي اشتراكات SR-6118 على الإعدادات الافتراضية
يمكن تعيين جميع معلمات الدالة على القيمة الافتراضية. قم بإنشاء بنية Box تحتوي على مصفوفة من العناصر ، ووظيفة ثانوية للوصول إليها.struct Box {
let items: [String]
subscript(_ index: Int = 0) -> String {
items[index]
}
}
الآن ، للوصول إلى العنصر الأول ، يمكنك حذف الفهرس:let box = Box(items: ["laptop, , mobile phone"])
let firstItem = box[]
تدعم وظائف SR-2189 المحلية المعلمات الافتراضية من الرؤية الخارجية
في الممارسة اليومية ، نادرًا ما يتم استخدام الوظائف المحلية. قد يكون من الصعب تبرير استخدامها. ومع ذلك ، أعترف أنه في بعض الحالات قد يكون هذا مفيدًا.على سبيل المثال ، سننشئ دالة سنصف فيها وظيفة محلية:func getXPosition() {
func calculateWidth(x: CGFloat = minX) -> CGFloat { ... }
let minX: CGFloat = 0
...
}
كمعلمة افتراضية للدالة calculateWidth ، يمكننا استخدام القيم داخل دالة getXPosition.الوظيفة ، على غرارdynamicCallable ، تسمح لك باستخدام قيمة كدالة. ولكنه تنفيذ "نداء ثابت".عمليًا ، كل شيء بسيط للغاية: لاستدعاء الوظائف ، يمكنك الرجوع إلى القيم كطرق.إنشاء هيكل لاعب:struct Player {
private(set) var isRunning = false
mutating func callAsFunction() {
isRunning.toggle()
}
}
قم بإنشاء مثيل لـ Player وقم بالإشارة إليه كوظيفة:var player = Player()
print(player.isRunning)
player()
print(player.isRunning)
في الوقت نفسه ، يُمنع إلقاء ، وبالتالي تمرير كائن كدالة:
let playerAsFunc = player as () -> Void
يمكنك إضافة العديد من الطرق مثل callAsFunction إلى فئة أو بنية أو بروتوكول:extension Player {
func callAsFunction(isRunning: Bool = false) throws { ... }
func callAsFunction() -> Bool { ... }
}
التطبيق ممكن في القيم التي هي وظائف رياضية أو تعبيرات معقدة أو في الحالات التي تكون فيها القيمة دالة مهيمنة واحدة. ومع ذلك ، يجب عدم إساءة استخدام هذه الوظيفة ، فقد تكون مضللة.SR-4206 خطأ ثابت مع تجاوز الوظيفة بمعلمة عامة
الآن ، بعد تجاوز الوظيفة ، لا يمكنك تغيير أو إضافة قيود على النوع العام. كمثال ، قم بإنشاء فئة CarBuilder والوراثة منها عن طريق تجاوز طريقة الإضافة:protocol PowerfullEngine { }
class CarBuilder {
func add<T>(engine: T) {}
}
class MercedesBuilder: CarBuilder {
override func add<T>(engine: T) {}
override func add<T: PowerfullEngine>(engine: T) {}
}
SR-11298 توسيع بروتوكول بدون قيود فئة يرث هذا التقييد
في حالة القيود المفروضة على الذات ، سيطبق التمديد القيد.على سبيل المثال ، قم بإنشاء القائمة والبروتوكول الملحق مع تقييد الفئة:protocol Menu {}
class SideMenu: Menu {
var sectionHeight = 0
}
extension Menu where Self: SideMenu {
var menuHeight: Int {
get { sectionHeight * 20 }
set { sectionHeight = newValue / 20 }
}
}
في الوقت نفسه ، فإن أداة الضبط غير متقطعة ، كما لو أن البروتوكول له تقييد فئة.صب 11429 ريال للوظائف ذات الملصقات
عند إزالة وظائف الصب لكتابة التسميات الآن. بفضل هذا ، يمكنك إلقاء الوظائف باستخدام التسميات. في السابق ، كانت هذه الوظيفة تعمل فقط في الوظائف التي لا تحتوي على تصنيفات:func setX(x: Int) {}
(setX as (Int) -> Void)(5)
ومع ذلك ، لن يتم حفظ القيم الافتراضية:func setPoint(x: Int, y: Int = 0) {}
(setPoint as (Int, Int) -> Void)(5, 1)
ينطبق هذا أيضًا على الأدوية العامة ، لذلك لم يعد هذا الرمز صالحًا.typealias Point<T> = T
func set(x: Int) {}
(set as Point)(5)
(set as Point)(x: 5)
SR-11841 يتم استدعاء دالة التصفية (_ :) بالترتيب المتوقع في المجموعات البطيئة
قم بإنشاء مجموعة كسولة واستدعي طريقة العد:let lazyArray = [0]
.lazy
.filter { _ in print("A"); return true }
.filter { _ in print("B"); return true }
_ = lazyArray.count
كانت نتيجة المكالمة عكس ذلك من قبل: B A.SR-2790 يقوم عدد من مُهيئي النوع من عائلة UnsafePointer / UnsafeBufferPointer بإصدار تحذير الآن
ينطبق القيد على السلاسل ، والمصفوفات ، ومعاملات Inout غير الموجودة خارج استدعاء الوظيفة.إنشاء بنية تأخذ UnsafePointer كمعلمة أثناء التهيئة:struct Game {
let info: UnsafePointer<Int8>
}
func createGame() {
var i: Int8 = 0
_ = Game(info: .init(&i))
_ = Game(info: [1, 2])
_ = Game(info: "")
}
كانت هناك 9 تغييرات في هذا الإصدار ، ومع ذلك ، فقد قدموا بالتأكيد وظائف جديدة. أفترض أن الأكثر استخدامًا حاليًا هو KeyPath كدالة.ونتطلع إلى الإصدار التالي. على ما يبدو ، ستدعم Swift على Windows وستظهر ميزات مثيرة للاهتمام ، مثل استخدام الذات في الهروب من عمليات الإغلاق دون الوصول من خلال الذات. * ( SE-0269 ) ووظائف الأدوية العامة ( SE-0267 ) ستتوسع .مصدر