ظهر الإصدار التجريبي الأول من Swift 5.2 للتو في Xcode 11.4 beta ، وكانت هناك تغييرات في اللغة ، جنبًا إلى جنب مع تقليل حجم الرمز والذاكرة المستخدمة ، بالإضافة إلى نظام تشخيص جديد سيسمح لك باكتشاف الأخطاء بسرعة.استخدام تعبيرات KeyPath كوظائف
نحدد الهيكل التالي:struct User {
let name: String
let age: Int
let bestFriend: String?
var canVote: Bool {
age >= 18
}
}
دعنا ننشئ بعض أمثلة هيكلنا ونضعها في مصفوفة:let eric = User(name: "Eric Effiong", age: 18, bestFriend: "Otis Milburn")
let maeve = User(name: "Maeve Wiley", age: 19, bestFriend: nil)
let otis = User(name: "Otis Milburn", age: 17, bestFriend: "Eric Effiong")
let users = [eric, maeve, otis]
إنتبه الآن: إذا كنت تريد الحصول على مجموعة من أسماء جميع المستخدمين ، يمكنك القيام بذلك على النحو التالي:let userNames = users.map(\.name)
print(userNames)
في السابق ، كنا بحاجة إلى استخدام الإغلاق:let oldUserNames = users.map { $0.name }
بنفس الطريقة الجديدة ، يمكنك الحصول على جميع المستخدمين الذين يمكنهم التصويت:let voters = users.filter(\.canVote)
وهنا نحصل على كل من لديه أفضل صديق:let bestFriends = users.compactMap(\.bestFriend)
قيم الأنواع المعرفة من قبل المستخدم
قم بإنشاء بنية النرد بخصائص lowerBound و upperBound ، ثم قم بإضافة وظيفة callAsFunction . وهكذا ، في كل مرة نحصل على قيمة النرد ، سنحصل على قيمة عشوائية:struct Dice {
var lowerBound: Int
var upperBound: Int
func callAsFunction() -> Int {
(lowerBound...upperBound).randomElement()!
}
}
let d6 = Dice(lowerBound: 1, upperBound: 6)
let roll1 = d6()
print(roll1)
هنا نحصل على رقم عشوائي من 1 إلى 6 ، وهذا مطابق تمامًا لمكالمة مباشرة مع callAsFunction (). يمكننا أن نفعل نفس الشيء مثل هذا:let d12 = Dice(lowerBound: 1, upperBound: 12)
let roll2 = d12.callAsFunction()
print(roll2)
يحدد Swift تلقائيًا المكالمة الصحيحة بناءً على كيفية تعريف callAsFunction (). على سبيل المثال ، يمكنك إضافة العديد من المعلمات ، وتغيير القيمة المرجعة ، وحتى إذا لزم الأمر ، ضع علامة على الطريقة على أنها طفرة.سنقوم هنا بإنشاء هيكل StepCounter الذي يلتقط عدد الخطوات التي تم اتخاذها ويشير إلى ما إذا كان عدد الخطوات المكتملة قد وصل إلى 10000:struct StepCounter {
var steps = 0
mutating func callAsFunction(count: Int) -> Bool {
steps += count
print(steps)
return steps > 10_000
}
}
var steps = StepCounter()
let targetReached = steps(count: 10)
يدعم callAsFunction () أيضًا الرميات والسحابات ، ويمكنك تحديد العديد من طرق callAsFunction () ، كما هو الحال مع التحميل الزائد المنتظم.يمكن أن يعلن منخفض الوسيطات الافتراضية
عند إضافة اشتراكات لنوع ، يمكنك استخدام الوسيطات الافتراضية. على سبيل المثال ، إذا كان لدينا هيكل PoliceForce مع خط منخفض مخصص لسرد الضباط في الوحدة ، فيمكننا إضافة معلمة افتراضية لإعادتها إذا تمت قراءة المصفوفة خارج حدودها:struct PoliceForce {
var officers: [String]
subscript(index: Int, default default: String = "Unknown") -> String {
if index >= 0 && index < officers.count {
return officers[index]
} else {
return `default`
}
}
}
let force = PoliceForce(officers: ["Amy", "Jake", "Rosa", "Terry"])
print(force[0])
print(force[5])
هنا نحصل على "Amy" ثم "Unknown" في الإخراج ، حيث لا يوجد لدينا عنصر مصفوفة مع الفهرس 5.نظرًا لأننا كتبنا افتراضيًا افتراضيًا ، يمكننا تعيين قيمة مخصصة ، مثل:print(force[-1, default: "The Vulture"])
التشخيصات الجديدة والمحسنة
يقدم Swift 5.2 بنية تشخيصية جديدة تهدف إلى تحسين جودة ودقة رسائل خطأ تطوير Xcode. هذا ملحوظ بشكل خاص عند العمل مع رمز SwiftUI ، حيث يولد Swift غالبًا رسائل خطأ إيجابية خاطئة.على سبيل المثال ، خذ بعين الاعتبار الرمز التالي:struct ContentView: View {
@State private var name = 0
var body: some View {
VStack {
Text("What is your name?")
TextField("Name", text: $name)
.frame(maxWidth: 300)
}
}
}
هنا نحاول ربط عرض TextField بعدد صحيح حالةالممتلكات التي هي خاطئة. في هذه الحالة ، سينتج Swift 5.1 خطأ في معدّل الإطار () "Int" غير قابل للتحويل إلى "CGFloat؟" لكن Swift 5.2 والإصدارات الأحدث تتعرف بشكل صحيح على الخطأ في ربط $ name: لا يمكن تحويل قيمة النوع "Binding" إلى نوع الوسيطة المتوقع "Binding".