سويفت 5.2 - ما الجديد؟

ظهر الإصدار التجريبي الأول من 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".

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


All Articles