- كل المقالات
- استخدام الأنواع العامة مع typealias في Swift
استخدام الأنواع العامة مع typealias في Swift
استخدم typealias لتسمية دوال الإكمال وتوحيد توقيعاتها، مع تغيير نوع الاستجابة حسب الحاجة. اسم أوضح للشيفرة، دون إنشاء نوع جديد.
يعطي typealias اسمًا بديلًا لنوع موجود. مثلًا، TimeInterval اسم بديل لـ
Double يوضح أن القيمة تمثل مدة زمنية.
ويمكن أن يأخذ الاسم البديل وسيطًا نوعيًا. أستخدم ذلك كثيرًا لتسمية دوال الإكمال:
struct Service {
typealias Handler<Response> = (Result<Response, APIError>) -> Void
func fetchPost(id: Int, _ completion: @escaping Handler<Post>) { ... }
func fetchPosts(_ completion: @escaping Handler<[Post]>) { ... }
func fetchBooks(_ completion: @escaping Handler<[Book]>) { ... }
}
بدون Handler، نكرر توقيع الدالة (Result<Post, APIError>) -> Void مع تغيير
نوع الاستجابة في كل مرة. الاسم البديل يوضح الجزء المشترك: كل دالة إكمال تستقبل
Result، ونوع الخطأ واحد في جميع الحالات.
إذا تغير نوع الخطأ، يكفي تعديل تعريف Handler بدل البحث عن كل توقيع يذكر
APIError.
ويمكن استخدامه أيضًا لاختصار اسم طويل من مكتبة خارجية:
final class Service {
typealias Book = SLBSomeLibraryServiceBookModel
func loadBooks() -> [Book] { ... }
}
داخل Service، يبقى معنى Book واضحًا ويمكن العثور على تعريفه بسهولة. أما
الأسماء المختصرة في نطاق أوسع فقد تربك القارئ، خصوصًا إذا كانت عدة وحدات
تستخدم الاسم نفسه لأنواع مختلفة.
لكن الاسم الجديد لا ينشئ نوعًا جديدًا. Handler<Post> و(Result<Post, APIError>) -> Void هما النوع نفسه بالنسبة للمترجم، ويمكن استخدام أحدهما مكان
الآخر. إذا أردت تمييز دالة الإكمال الخاصة بخدمتك عن غيرها، فستحتاج إلى نوع
مستقل يغلّفها.
فائدة typealias هنا في وضوح الواجهة وسهولة تعديلها؛ أما الفصل بين الأنواع
فيحتاج إلى أداة أخرى.
لدى Antoine van der Lee شرح أوسع لاستخدام typealias مع أمثلة إضافية.
هل تستخدم typealias جعل واجهة معقدة أسهل في القراءة؟ يسعدني أن أرى
مثالك. ويمكنك مشاركة هذه الملاحظة مع زميل يبحث عن أسماء أوضح في
شيفرته.