EduFlow
أساسيات Swift لتطبيقات iOS
⁦0%⁩

الوحدة 1 · لغة Swift

الثوابت والمتغيّرات والأنواع

12 دقراءة 3 داختر بحكمة

الدرس في لمحة

عرّف الثوابت والمتغيّرات، واقرأ الأنواع التي تستنتجها Swift لك، واختر نوع الأرقام المناسب للمال في Pocket Budget.

  1. 1let وvar
  2. 2استنتاج النوع
  3. 3لا تحويلات صامتة
  4. 4المال ليس Double

لا فيديو هنا، بل الشيء الحقيقي: درس مكتوب وأمثلة قابلة للتشغيل واختبار وتدريب.

أراجع كل عام كودًا كتبه مطوّرو iOS جدد، وأغلب تقارير الأعطال تعود إلى العادات القليلة نفسها: قيم تتغيّر حين لم يتوقّع أحد ذلك، وأرقام تفقد دقّتها بصمت، وافتراضات كان بإمكان الـ compiler (المترجِم) أن يكتشفها. صُمّمت Swift لتلتقط هذه الأخطاء بالتحديد، لكن بشرط أن تعمل مع نظام الأنواع لا أن تلتفّ عليه.

خلال هذه الدورة ستبني Pocket Budget، تطبيق iPhone صغيرًا يتتبّع ما تنفقه. يبدأ هنا بعدد قليل من القيم داخل playground في Xcode، وينتهي تطبيقًا بـ SwiftUI على TestFlight. لتتابع معي، افتح Xcode، واختر File › New › Playground، ثم اختر القالب Blank، واكتب الأمثلة. الـ playground (ملف التجارب) يشغّل الكود وأنت تكتبه ويعرض نتيجة كل سطر في الشريط الجانبي.

let وvar

في Swift طريقتان لتسمية قيمة. let تعرّف ثابتًا يُسنَد مرة واحدة. وvar تعرّف متغيّرًا يمكن أن يتغيّر.

PocketBudget.playground
let monthlyLimit = 1500
var spentSoFar = 0

spentSoFar = spentSoFar + 42
spentSoFar += 18          // shorthand for the line above
// monthlyLimit = 2000    // error: cannot assign to value: 'monthlyLimit' is a 'let' constant

استخدم let افتراضيًا. حين تكون القيمة ثابتة، لن تتساءل أبدًا من الذي غيّرها. وإن احتجت إلى تغييرها لاحقًا، يخبرك الـ compiler بذلك، ويعرض عليك Xcode إصلاحًا بنقرة واحدة يحوّل let إلى var. وفي الاتجاه المعاكس، يحذّرك Xcode حين لا يتغيّر var أبدًا. تعامل مع هذا التحذير كطلب لترتيب الكود.

استنتاج النوع

لم تكتب نوعًا واحدًا في المثال السابق، ومع ذلك لكل قيمة نوع (type). Swift تستنتج النوع من أول قيمة تسندها:

Swift
let category = "Coffee"     // String
let cups = 3                // Int
let pricePerCup = 4.5       // Double
let isRecurring = false     // Bool

اضغط Option مع النقر على أي اسم في Xcode لترى نوعه المستنتَج. ويمكنك أيضًا أن تكتب النوع بنفسك عبر تحديد صريح للنوع (type annotation)، وهذا مفيد حين تختار القيمة المكتوبة وحدها النوع الخطأ:

Swift
let fee: Double = 3         // without the annotation, 3 would be an Int

متى أخذت القيمة نوعًا احتفظت به. لا يمكنك أن تضع String داخل cups لاحقًا. وهذا ما يجعل كود Swift مقروءًا بعد أشهر: الاسم يعني نوعًا واحدًا من الأشياء، إلى الأبد.

لا تحويلات صامتة

هذا هو السطر الذي يفاجئ القادمين من JavaScript أو Python:

Swift
let cups = 3
let pricePerCup = 4.5
// let total = cups * pricePerCup   // error: binary operator '*' cannot be applied to operands of type 'Int' and 'Double'
let total = Double(cups) * pricePerCup   // 13.5

لا تحوّل Swift قيمة Int إلى Double (أو العكس) من وراء ظهرك. أنت تكتب التحويل، فيراه القارئ. وتحويل Double إلى Int بالكتابة Int(13.5) يحذف الكسر ويعطي 13، وهذا بالضبط نوع القرارات التي تريدها ظاهرة أثناء مراجعة الكود.

المال ليس Double

النوع Double فاصلة عائمة ثنائية. هو سريع ومثالي للمسافات أو توقيت الحركات، لكنه لا يستطيع تخزين معظم الكسور العشرية بدقة. أضف عشرة سنتات عشر مرات وانظر إلى النتيجة:

Swift
import Foundation

var withDouble = 0.0
var withDecimal: Decimal = 0
for _ in 1...10 {
    withDouble += 0.1
    withDecimal += 0.1
}
print(withDouble)    // 0.9999999999999999
print(withDecimal)   // 1

تطبيق ميزانية يقول إنك أنفقت $0.9999999999999999 يفقد ثقة المستخدم فورًا. أما Decimal، القادم من Foundation، فيخزّن أرقامًا بالنظام العشري، فتبقى السنتات دقيقة. يستخدم Pocket Budget النوع Decimal لكل مبلغ، وستراه في معظم الدروس من الآن فصاعدًا.

لكن انتبه إلى أمر واحد: القيمة الكسرية المكتوبة مباشرة مثل let tip: Decimal = 0.07 تُقرأ أولًا على أنها Double ثم تُحوَّل، فقد تصل بالشكل 0.07000000000000001024. المبالغ القصيرة في الأمثلة مثل 4.5 أو 12.99 تمرّ سليمة، أما المبالغ التي تهمّ فعلًا فابنِ الـ Decimal فيها من نص (Decimal(string: "0.07")) أو من عدد السنتات الصحيح (Decimal(7) / 100).

صار لديك الآن ثوابت ومتغيّرات والأنواع التي خلفها. في الدرس التالي تتعرّف على النوع الذي جعل Swift مشهورة بالأمان: الـ optional، وهو طريقة Swift لتقول «قد لا توجد قيمة هنا».

أهم النقاط

  • استخدم let افتراضيًا، ولا تنتقل إلى var إلا عندما يخبرك الـ compiler أن القيمة يجب أن تتغيّر.
  • تستنتج Swift النوع من أول قيمة تسندها، ولا يتغيّر هذا النوع بعد ذلك أبدًا.
  • لا تحوّل Swift بين Int وDouble بصمت؛ أنت من يكتب التحويل صراحةً، فلا تفاجئك العمليات الحسابية بين نوعين مختلفين.
  • خزّن المال بالنوع Decimal لا Double، لأن الفاصلة العائمة الثنائية لا تستطيع تمثيل معظم السنتات بدقة.

قراءات إضافية

تحقّق من فهمك

3 أسئلة

السؤال 1 من 3

كتبت let limit = 300 ثم لاحقًا limit = 350. ماذا يحدث؟

السؤال 2 من 3

ما النوع الذي تستنتجه Swift للتعريف let coffee = 4.5؟

السؤال 3 من 3

عرّفت let rent = 1200 وlet fee = 2.5. لماذا لا يُترجَم rent + fee؟

تدريب

اختر بحكمة

أيّ الأسطر تُترجَم؟

في أول playground لتطبيق Pocket Budget بضعة أسطر سيرفضها الـ compiler في Swift. كل خيار أدناه مقطع كامل قائم بذاته. اختر كل مقطع يُترجَم دون أخطاء.

أيّ الأسطر تُترجَم؟