{"id":"l-sw-1-1","courseId":"swift-essentials","lang":"ar","kind":"intro","summary":"عرّف الثوابت والمتغيّرات، واقرأ الأنواع التي تستنتجها Swift لك، واختر نوع الأرقام المناسب للمال في Pocket Budget.","html":"<p>أراجع كل عام كودًا كتبه مطوّرو iOS جدد، وأغلب تقارير الأعطال تعود إلى العادات القليلة نفسها: قيم تتغيّر حين لم يتوقّع أحد ذلك، وأرقام تفقد دقّتها بصمت، وافتراضات كان بإمكان الـ compiler (المترجِم) أن يكتشفها. صُمّمت Swift لتلتقط هذه الأخطاء بالتحديد، لكن بشرط أن تعمل مع نظام الأنواع لا أن تلتفّ عليه.</p>\n<p>خلال هذه الدورة ستبني <strong>Pocket Budget</strong>، تطبيق iPhone صغيرًا يتتبّع ما تنفقه. يبدأ هنا بعدد قليل من القيم داخل playground في Xcode، وينتهي تطبيقًا بـ SwiftUI على TestFlight. لتتابع معي، افتح Xcode، واختر File › New › Playground، ثم اختر القالب Blank، واكتب الأمثلة. الـ playground (ملف التجارب) يشغّل الكود وأنت تكتبه ويعرض نتيجة كل سطر في الشريط الجانبي.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">let وvar</h2>\n<p>في Swift طريقتان لتسمية قيمة. <code dir=\"ltr\">let</code> تعرّف ثابتًا يُسنَد مرة واحدة. و<code dir=\"ltr\">var</code> تعرّف متغيّرًا يمكن أن يتغيّر.</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">PocketBudget.playground</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> monthlyLimit </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 1500</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">var</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> spentSoFar </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">spentSoFar </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> spentSoFar </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 42</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">spentSoFar </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 18</span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">          // shorthand for the line above</span></span>\n<span class=\"line\"><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// monthlyLimit = 2000    // error: cannot assign to value: 'monthlyLimit' is a 'let' constant</span></span></code></pre></div>\n<p>استخدم <code dir=\"ltr\">let</code> افتراضيًا. حين تكون القيمة ثابتة، لن تتساءل أبدًا من الذي غيّرها. وإن احتجت إلى تغييرها لاحقًا، يخبرك الـ compiler بذلك، ويعرض عليك Xcode إصلاحًا بنقرة واحدة يحوّل <code dir=\"ltr\">let</code> إلى <code dir=\"ltr\">var</code>. وفي الاتجاه المعاكس، يحذّرك Xcode حين لا يتغيّر <code dir=\"ltr\">var</code> أبدًا. تعامل مع هذا التحذير كطلب لترتيب الكود.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">استنتاج النوع</h2>\n<p>لم تكتب نوعًا واحدًا في المثال السابق، ومع ذلك لكل قيمة نوع (type). Swift <strong>تستنتج</strong> النوع من أول قيمة تسندها:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> category </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"Coffee\"</span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">     // String</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> cups </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 3</span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">                // Int</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pricePerCup </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 4.5</span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">       // Double</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> isRecurring </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> false</span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">     // Bool</span></span></code></pre></div>\n<p>اضغط Option مع النقر على أي اسم في Xcode لترى نوعه المستنتَج. ويمكنك أيضًا أن تكتب النوع بنفسك عبر تحديد صريح للنوع (type annotation)، وهذا مفيد حين تختار القيمة المكتوبة وحدها النوع الخطأ:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> fee: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">Double</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 3</span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">         // without the annotation, 3 would be an Int</span></span></code></pre></div>\n<p>متى أخذت القيمة نوعًا احتفظت به. لا يمكنك أن تضع <code dir=\"ltr\">String</code> داخل <code dir=\"ltr\">cups</code> لاحقًا. وهذا ما يجعل كود Swift مقروءًا بعد أشهر: الاسم يعني نوعًا واحدًا من الأشياء، إلى الأبد.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">لا تحويلات صامتة</h2>\n<p>هذا هو السطر الذي يفاجئ القادمين من JavaScript أو Python:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"3\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> cups </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 3</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pricePerCup </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 4.5</span></span>\n<span class=\"line\"><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// let total = cups * pricePerCup   // error: binary operator '*' cannot be applied to operands of type 'Int' and 'Double'</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> total </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> Double</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(cups) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">*</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pricePerCup   </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// 13.5</span></span></code></pre></div>\n<p>لا تحوّل Swift قيمة <code dir=\"ltr\">Int</code> إلى <code dir=\"ltr\">Double</code> (أو العكس) من وراء ظهرك. أنت تكتب التحويل، فيراه القارئ. وتحويل <code dir=\"ltr\">Double</code> إلى <code dir=\"ltr\">Int</code> بالكتابة <code dir=\"ltr\">Int(13.5)</code> يحذف الكسر ويعطي 13، وهذا بالضبط نوع القرارات التي تريدها ظاهرة أثناء مراجعة الكود.</p>\n<aside class=\"callout callout-note\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M12 16v-4\"/><path d=\"M12 8h.01\"/></svg><span><span class=\"callout-kind\">ملاحظة</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>القيم المكتوبة مرنة، والقيم المسمّاة ليست كذلك</span></p>\n<p>السطر <code dir=\"ltr\">let total = 1200 + 4.5</code> يُترجَم، لأن القيمتين المكتوبتين مباشرة ليس لهما نوع بعد، فتختار Swift النوع <code dir=\"ltr\">Double</code> لكلتيهما. لا يظهر الخطأ إلا حين يكون للقيمة نوع ثابت بالفعل.</p>\n</aside>\n<h2 id=\"sec-4\" tabindex=\"-1\">المال ليس Double</h2>\n<p>النوع <code dir=\"ltr\">Double</code> فاصلة عائمة ثنائية. هو سريع ومثالي للمسافات أو توقيت الحركات، لكنه لا يستطيع تخزين معظم الكسور العشرية بدقة. أضف عشرة سنتات عشر مرات وانظر إلى النتيجة:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"4\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#953800;--shiki-dark:#FFA657\"> Foundation</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">var</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> withDouble </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0.0</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">var</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> withDecimal: Decimal </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">for</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> _</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> in</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 1</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">...</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">10</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    withDouble </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0.1</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    withDecimal </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0.1</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(withDouble)    </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// 0.9999999999999999</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(withDecimal)   </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// 1</span></span></code></pre></div>\n<p>تطبيق ميزانية يقول إنك أنفقت $0.9999999999999999 يفقد ثقة المستخدم فورًا. أما <code dir=\"ltr\">Decimal</code>، القادم من Foundation، فيخزّن أرقامًا بالنظام العشري، فتبقى السنتات دقيقة. يستخدم Pocket Budget النوع <code dir=\"ltr\">Decimal</code> لكل مبلغ، وستراه في معظم الدروس من الآن فصاعدًا.</p>\n<p>لكن انتبه إلى أمر واحد: القيمة الكسرية المكتوبة مباشرة مثل <code dir=\"ltr\">let tip: Decimal = 0.07</code> تُقرأ أولًا على أنها <code dir=\"ltr\">Double</code> ثم تُحوَّل، فقد تصل بالشكل <code dir=\"ltr\">0.07000000000000001024</code>. المبالغ القصيرة في الأمثلة مثل <code dir=\"ltr\">4.5</code> أو <code dir=\"ltr\">12.99</code> تمرّ سليمة، أما المبالغ التي تهمّ فعلًا فابنِ الـ <code dir=\"ltr\">Decimal</code> فيها من نص (<code dir=\"ltr\">Decimal(string: &quot;0.07&quot;)</code>) أو من عدد السنتات الصحيح (<code dir=\"ltr\">Decimal(7) / 100</code>).</p>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">خطأ شائع</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>تنسيق المال يدويًا</span></p>\n<p>الكتابة <code dir=\"ltr\">&quot;$&quot; + String(describing: amount)</code> تنكسر أول مرة يفتح فيها مستخدم من ألمانيا أو اليابان تطبيقك. استخدم <code dir=\"ltr\">amount.formatted(.currency(code: &quot;USD&quot;))</code>، الذي يطبّق الرمز والفواصل وعدد المنازل العشرية المناسبة للإعدادات المحلية للمستخدم.</p>\n</aside>\n<p>صار لديك الآن ثوابت ومتغيّرات والأنواع التي خلفها. في الدرس التالي تتعرّف على النوع الذي جعل Swift مشهورة بالأمان: الـ optional، وهو طريقة Swift لتقول «قد لا توجد قيمة هنا».</p>\n","toc":[{"id":"sec-1","text":"let وvar","level":2},{"id":"sec-2","text":"استنتاج النوع","level":2},{"id":"sec-3","text":"لا تحويلات صامتة","level":2},{"id":"sec-4","text":"المال ليس Double","level":2}],"takeaways":["استخدم <code dir=\"ltr\">let</code> افتراضيًا، ولا تنتقل إلى <code dir=\"ltr\">var</code> إلا عندما يخبرك الـ compiler أن القيمة يجب أن تتغيّر.","تستنتج Swift النوع من أول قيمة تسندها، ولا يتغيّر هذا النوع بعد ذلك أبدًا.","لا تحوّل Swift بين <code dir=\"ltr\">Int</code> و<code dir=\"ltr\">Double</code> بصمت؛ أنت من يكتب التحويل صراحةً، فلا تفاجئك العمليات الحسابية بين نوعين مختلفين.","خزّن المال بالنوع <code dir=\"ltr\">Decimal</code> لا <code dir=\"ltr\">Double</code>، لأن الفاصلة العائمة الثنائية لا تستطيع تمثيل معظم السنتات بدقة."],"further":[{"title":"The Basics (The Swift Programming Language)","url":"https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics/"},{"title":"Decimal","url":"https://developer.apple.com/documentation/foundation/decimal"}],"quiz":[{"q":"<p>كتبت <code dir=\"ltr\">let limit = 300</code> ثم لاحقًا <code dir=\"ltr\">limit = 350</code>. ماذا يحدث؟</p>","options":[{"text":"يُترجَم الكود، وتصبح قيمة <code dir=\"ltr\">limit</code> الآن 350.","why":"هذا صحيح لو استخدمت <code dir=\"ltr\">var</code>. أما الثابت المعرّف بـ <code dir=\"ltr\">let</code> فيُسنَد مرة واحدة فقط."},{"text":"يرفض الـ compiler السطر الثاني: <code dir=\"ltr\">limit</code> ثابت معرّف بـ <code dir=\"ltr\">let</code>.","why":"صحيح. تكتشف Swift إعادة الإسناد وقت الترجمة، قبل أن يعمل التطبيق."},{"text":"يُترجَم الكود، لكن التطبيق يتعطّل عند تنفيذ ذلك السطر.","why":"لا تؤجّل Swift هذا الفحص إلى وقت التشغيل. قابلية التغيير يفحصها الـ compiler."}],"answer":1},{"q":"<p>ما النوع الذي تستنتجه Swift للتعريف <code dir=\"ltr\">let coffee = 4.5</code>؟</p>","options":[{"text":"<code dir=\"ltr\">Float</code>","why":"تختار Swift النوع <code dir=\"ltr\">Double</code> للرقم العشري المكتوب مباشرة، إلا إذا طلبت <code dir=\"ltr\">Float</code> صراحةً."},{"text":"<code dir=\"ltr\">Decimal</code>","why":"لا يُستنتج <code dir=\"ltr\">Decimal</code> أبدًا من قيمة مكتوبة مباشرة؛ عليك أن تحدّده بنفسك، كما في <code dir=\"ltr\">let coffee: Decimal = 4.5</code>."},{"text":"<code dir=\"ltr\">Double</code>","why":"صحيح. القيمة المكتوبة التي فيها جزء كسري تصبح <code dir=\"ltr\">Double</code> افتراضيًا."}],"answer":2},{"q":"<p>عرّفت <code dir=\"ltr\">let rent = 1200</code> و<code dir=\"ltr\">let fee = 2.5</code>. لماذا لا يُترجَم <code dir=\"ltr\">rent + fee</code>؟</p>","options":[{"text":"لأن <code dir=\"ltr\">rent</code> من النوع <code dir=\"ltr\">Int</code> و<code dir=\"ltr\">fee</code> من النوع <code dir=\"ltr\">Double</code>، وSwift لا تخلط بينهما أبدًا دون تحويل صريح.","why":"صحيح. اكتب <code dir=\"ltr\">Double(rent) + fee</code> وتكون قد صرّحت بالتحويل الذي تريده."},{"text":"لا يمكن استخدام الثوابت في العمليات الحسابية؛ المتغيّرات فقط يمكنها ذلك.","why":"الثوابت تعمل في أي تعبير. المشكلة في اختلاف النوعين."},{"text":"العامل <code dir=\"ltr\">+</code> يعمل على النصوص فقط في Swift.","why":"العامل <code dir=\"ltr\">+</code> يعمل على الأرقام والنصوص، لكن يجب أن يكون الطرفان من النوع نفسه."}],"answer":0}],"exercise":{"kind":"choice","multiple":true,"options":["reassign-let","increment-var","literal-sum","mixed-sum","string-to-int","annotated-double"],"correct":["increment-var","literal-sum","annotated-double"],"title":"أيّ الأسطر تُترجَم؟","prompt":"<p>في أول playground لتطبيق Pocket Budget بضعة أسطر سيرفضها الـ compiler في Swift. كل خيار أدناه مقطع كامل قائم بذاته. اختر <strong>كل</strong> مقطع يُترجَم دون أخطاء.</p>\n","hints":["اسأل سؤالين عن كل مقطع: هل أُسند شيء مرتين باستخدام <code dir=\"ltr\">let</code>؟ وهل يخلط أي عامل بين قيمتين نوعاهما محدّدان مسبقًا؟","القيم المكتوبة مباشرة مثل <code dir=\"ltr\">1200</code> و<code dir=\"ltr\">4.5</code> ليس لها نوع حتى تختار Swift نوعًا لها، لذلك يمكنها أن تتكيّف مع بعضها.","التحديد الصريح للنوع مثل <code dir=\"ltr\">: Double</code> يخبر Swift كيف تقرأ القيمة المكتوبة التي تليه."],"explanation":"<p>ثلاثة مقاطع تُترجَم. <code dir=\"ltr\">var spent</code> يمكن أن يتغيّر، فالعامل <code dir=\"ltr\">+=</code> مقبول. و<code dir=\"ltr\">1200 + 4.5</code> قيمتان مكتوبتان بلا نوع، فتجعل Swift كلتيهما <code dir=\"ltr\">Double</code>. و<code dir=\"ltr\">let fee: Double = 3</code> يقرأ الرقم الصحيح على أنه <code dir=\"ltr\">Double</code> بسبب تحديد النوع.</p>\n<p>أما المقاطع الثلاثة الأخرى فتفشل لأسباب ستقابلها كل أسبوع: الثابت المعرّف بـ <code dir=\"ltr\">let</code> لا يُعاد إسناده، وقيمة <code dir=\"ltr\">Int</code> لا تُجمع مع قيمة <code dir=\"ltr\">Double</code> دون <code dir=\"ltr\">Double(rent)</code>، والمتغيّر من النوع <code dir=\"ltr\">String</code> لا يمكن أن يحمل <code dir=\"ltr\">Int</code> أبدًا.</p>\n","checkLabels":{},"optionText":{"reassign-let":{"text":"<code dir=\"ltr\">let budget = 500; budget = 450</code>","why":"الثابت المعرّف بـ <code dir=\"ltr\">let</code> يُسنَد مرة واحدة فقط. استخدم <code dir=\"ltr\">var</code> إن كانت الميزانية تتغيّر فعلًا."},"increment-var":{"text":"<code dir=\"ltr\">var spent = 0; spent += 12</code>","why":"يُترجَم. <code dir=\"ltr\">spent</code> متغيّر من النوع <code dir=\"ltr\">Int</code>، وإضافة <code dir=\"ltr\">Int</code> إليه مسموحة."},"literal-sum":{"text":"<code dir=\"ltr\">let total = 1200 + 4.5</code>","why":"يُترجَم. الطرفان قيمتان مكتوبتان مباشرة، فتختار Swift النوع <code dir=\"ltr\">Double</code> لكليهما وتصبح قيمة <code dir=\"ltr\">total</code> هي <code dir=\"ltr\">1204.5</code>."},"mixed-sum":{"text":"<code dir=\"ltr\">let rent = 1200; let coffee = 4.5; let sum = rent + coffee</code>","why":"يفشل. <code dir=\"ltr\">rent</code> صار <code dir=\"ltr\">Int</code> و<code dir=\"ltr\">coffee</code> صار <code dir=\"ltr\">Double</code>؛ اكتب <code dir=\"ltr\">Double(rent) + coffee</code>."},"string-to-int":{"text":"<code dir=\"ltr\">var label: String = &quot;Coffee&quot;; label = 42</code>","why":"يفشل. المتغيّر يحتفظ بنوعه طوال حياته؛ <code dir=\"ltr\">label</code> لا يمكن أن يحمل إلا <code dir=\"ltr\">String</code>."},"annotated-double":{"text":"<code dir=\"ltr\">let fee: Double = 3</code>","why":"يُترجَم. تحديد النوع يخبر Swift أن تعامل الرقم الصحيح <code dir=\"ltr\">3</code> على أنه <code dir=\"ltr\">Double</code>."}}},"words":545,"readMinutes":3}