Struct هو نوع قيمة (value type) في لغة Swift، يتم نسخ مثيلاته عند نقلها بين أجزاء الكود. على عكس الفئات، لا تدعم الهياكل الوراثة، لكنها تنفذ البروتوكولات، وتحتوي على خصائص وطرق، وتوفر إدارة ذاكرة يمكن التنبؤ بها بدون ARC. وفقاً لـ Swift Programming Language Guide, 2026، struct هو لبنة البناء الأساسية في Swift — حتى الأنواع القياسية Int و String و Array و Dictionary مطبقة كهياكل. توصي اللغة باستخدام الهياكل كخيار مفضل لنمذجة البيانات.
الرئيسية
Struct (هيكل) هو نوع بيانات مركب في Swift يجمع الخصائص والطرق ذات الصلة في كيان واحد. على عكس الفئات، الهياكل هي value types: عند تمريرها إلى دالة أو تعيينها لمتغير جديد، يتم إنشاء نسخة مستقلة من الهيكل، وليس مرجعاً للكائن الأصلي.
يستخدم Swift الهياكل لجميع الأنواع البدائية: Int و Double و String و Bool و Array و Dictionary و Set. هذا يعني أنه حتى الرقم Int الأساسي يتصرف كهيكل — يتم إنشاء نسخة عند التعيين. يمكن للمطور تعريف هيكله الخاص بأي مجموعة من الخصائص والطرق.
وفقاً لـ Swift Evolution (SE-0143)، فإن قرار تنفيذ الأنواع القياسية كهياكل يرجع إلى الأداء والقابلية للتنبؤ. لا تنشئ value types دورات مرجعية، ولا تتطلب عد المراجع ARC، وتضمن أن تعديل النسخة لا يؤثر على الأصل — وهذا مهم بشكل حاسم لثبات البيانات في السيناريوهات متعددة الخيوط.
دلالات value type هي الفرق الرئيسي بين struct و class. عندما تعين هيكلاً لمتغير جديد أو تمرره إلى دالة، ينشئ Swift نسخة مستقلة من جميع البيانات. أي تغييرات في النسخة لا تؤثر على الأصل، مما يلغي الآثار الجانبية النموذجية للأنواع المرجعية.
// مثال على دلالات نوع القيمة
struct Point {
var x: Double
var y: Double
}
var p1 = Point(x: 10, y: 20)
var p2 = p1 // p2 نسخة مستقلة من p1
p2.x = 99 // فقط p2 يتغير
print(p1.x) // 10 — p1 بدون تغيير
print(p2.x) // 99
يستخدم Swift Copy-on-Write (COW) لتحسين النسخ. إذا كانت متغيرات متعددة تشير إلى نفس الهيكل ولكن لا شيء منها يعدل البيانات، لا يحدث نسخ فعلي. يشارك Swift الذاكرة بين المتغيرات حتى أول تغيير — عندها يتم إنشاء نسخة حقيقية. هذا يمنع عمليات التخصيص الزائدة ويسرع العمل مع المجموعات.
افتراضياً، لا يمكن لطرق الهيكل تعديل خصائصه — يتطلب Swift الكلمة المفتاحية mutating بشكل صريح للطرق التي تجري تغييرات. هذا القيد يحمي من التغيير العرضي ويجعل الكود قابلاً للتنبؤ: إذا لم تكن الطريقة موسومة بـ mutating، فأنت مضمون عدم تغيير الهيكل.
عند إضافة الكلمة المفتاحية mutating قبل الطريقة، يحصل Swift على القدرة على كتابة قيم جديدة في خصائص الهيكل. في الواقع، يمكن للطريقة حتى استبدال مثيل الهيكل بالكامل بمثيل جديد عبر self =. هذه الآلية تُستخدم، على سبيل المثال، في أنواع Option و Result.
// Struct مع طريقة mutating
struct Counter {
private var value: Int = 0
// طريقة mutating — يمكنها تعديل الخصائص
mutating func increment() {
value += 1
}
// طريقة mutating يمكنها استبدال self بالكامل
mutating func reset() {
self = Counter()
}
// طريقة غير mutating — للقراءة فقط
func currentValue() -> Int {
return value
}
}
var counter = Counter()
counter.increment()
print(counter.currentValue()) // 1
counter.reset()
print(counter.currentValue()) // 0
قواعد mutating: يجب تعريف الهيكل باستخدام var وليس let — لا يمكن استدعاء طريقة mutating على هيكل ثابت. يتحقق المترجم من ذلك في وقت البناء: محاولة استدعاء طريقة mutating على ثابت let ستؤدي إلى خطأ في الترجمة.
الاختيار بين struct و class هو أحد القرارات الأساسية في Swift. يمكن لكلا النوعين احتواء خصائص وطرق ومهيآت وتنفيذ بروتوكولات، لكن لديهما اختلافات جوهرية في دلالات الذاكرة والوراثة وإدارة دورة الحياة.
| الخاصية | struct | class |
|---|---|---|
| النوع | Value type (يُنسخ) | Reference type (مرجع) |
| الوراثة | لا يدعم | يدعم |
| ARC / عد المراجع | غير مطلوب | ARC مطلوب |
| إزالة التهيئة | لا يدعم | يدعم deinit |
| تعديل الخصائص في الثوابت | فقط عبر var | ممكن عبر let (المرجع ثابت) |
| تحويل الأنواع | لا يدعم | يدعم |
| التخزين في المجموعات | يُخزن مباشرة (قيمة) | يُخزن كمرجع (مؤشر) |
الهياكل مفضلة عندما لا تتطلب البيانات وراثة، ولا يجب أن يكون لها هوية مشتركة (مثل الإحداثيات والأحجام والتكوين) وتُنقل بين الوحدات. تُختار الفئات لمكونات واجهة المستخدم (UIView, UIViewController) والكيانات الفردية والأشياء ذات الهوية المشتركة.
توصي Apple باستخدام struct كـ نوع افتراضي لنمذجة البيانات في Swift. الهياكل مناسبة لمعظم السيناريوهات بفضل دلالات النسخ القابلة للتنبؤ وغياب الحمل الزائد لعد المراجع. دعنا نستعرض الحالات النموذجية التي يكون فيها struct هو الخيار الأمثل.
إذا كان الكيان يحتوي على بيانات بدون حاجة للوراثة (Product, User, Order, Point)، استخدم struct. يُنشئ المترجم تلقائياً memberwise initializer — لست بحاجة لكتابة init يدوياً. يتم أيضاً تنفيذ Equatable و Hashable تلقائياً للهياكل التي تلتزم جميع خصائصها بهذه البروتوكولات.
للتكوينات والإعدادات والأعلام التي لا تتغير بعد الإنشاء، struct أفضل من class. الهيكل الثابت (let) يضمن ثبات جميع الحقول المتداخلة — في class هذا ينطبق فقط على المرجع، وليس على محتوى الكائن.
الهياكل آمنة في البيئات متعددة الخيوط بفضل دلالات القيمة. يحصل كل خيط على نسخة مستقلة من البيانات ولا يؤثر على الخيوط الأخرى. سباقات البيانات بين الخيوط مستحيلة لل value types، مما يجعل struct الخيار المفضل للنماذج في SwiftUI (ObservableObject يتطلب class، لكن @State يستخدم struct).
// مثال على استخدام struct لنموذج بيانات
struct User: Codable, Identifiable {
let id: UUID
var name: String
var email: String
var isPremium: Bool
// خاصية محسوبة — غير mutating
var displayName: String {
isPremium ? "\(name) ⭐️" : name
}
}
// مهيئ memberwise تلقائي
let user = User(
id: UUID(),
name: "Alice",
email: "alice@example.com",
isPremium: true
)
// النسخ آمن لتعدد الخيوط
var userCopy = user
userCopy.isPremium = false
// user.isPremium يبقى true
استخدم class عندما تحتاج وراثة (مكونات UIKit/AppKit)، هوية مشتركة (delegate, observer) أو دورة حياة متحكم بها للكائن (deinit). لكل شيء آخر — استخدم struct.
الأسئلة الشائعة
Struct في Swift هو نوع قيمة (value type) يُنسخ عند النقل بين أجزاء الكود. يمكن للهياكل احتواء خصائص وطرق ومهيآت وتنفيذ بروتوكولات. الأنواع الأساسية في Swift (Int, String, Array) مطبقة كهياكل.
Struct هو value type (يُنسخ عند التعيين)، لا يدعم الوراثة ولا يتطلب ARC. Class هو reference type (يُمرر بالمرجع)، يدعم الوراثة وإزالة التهيئة وعد المراجع. يوصي المطورون باستخدام struct كنوع افتراضي.
Mutating هي كلمة مفتاحية تشير إلى أن طريقة الهيكل يمكنها تعديل خصائصه. بدون mutating، يمنع المترجم تعديل الحقول. يمكن استدعاء طرق mutating فقط على المتغيرات المعلنة بـ var وليس let.
Copy-on-Write (COW) هو تحسين Swift للهياكل حيث يتم تأجيل النسخ الفعلي للبيانات حتى أول تغيير. طالما أن جميع المتغيرات تقرأ الهيكل فقط، فإنها تشارك منطقة ذاكرة واحدة. هذا يحسن الأداء عند العمل مع المجموعات الكبيرة.
استخدم struct لنماذج البيانات بدون وراثة والتكوينات و DTOs والسيناريوهات متعددة الخيوط. استخدم class لمكونات UIKit/AppKit والكيانات الفردية والكيانات ذات الهوية المشتركة (delegate, observer) والأشياء التي تتطلب إزالة تهيئة.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.