Swift والأرقام العشوائية: سحر يعمل بشكل متوقع
\n\nكل مطور يواجه عاجلاً أم آجلاً مهمة: "كيفية توليد رقم عشوائي؟". قد يبدو الأمر بسيطاً؟ لكن في عالم Swift، قطعت هذه الموضوع شوطاً طويلاً من التطور - من دوال C القديمة إلى API مدمج أنيق. في هذه المقالة، سنستعرض جميع طرق توليد الأرقام العشوائية في Swift، من البسيطة إلى الصناعية، مع أمثلة حية ونقاط مهمة.
\n\nإذا كنت تتساءل يوماً لماذا arc4random() الخاص بك يُرجع أرقاماً غريبة أو كيفية إجراء اختيار عشوائي حقيقي من مصفوفة - فقد وصلت إلى المكان الصحيح. هيا بنا!
تاريخ موجز: كيف وصلنا إلى هذه المرحلة
\n\nقبل Swift 4.2 (عام 2018)، كان المطورون يتخبطون بين arc4random() و drand48() والحلول المؤقتة مثل rand() % 100. الأخير، بالمناسبة، كان خطيراً - الانحياز (bias) في التوزيع مضمون إذا لم يكن النطاق قابلاً للقسمة على RAND_MAX. مع إصدار Swift 4.2، قدمت لنا Apple بروتوكول RandomNumberGenerator والطرق المدمجة. الآن أصبح توليد الأرقام العشوائية آمناً وقابلاً للقراءة وموحداً.
الطريقة الحديثة: RandomNumberGenerator وطرق الأنواع
\n\nبدءاً من Swift 4.2، الطريقة الأصح والأبسط هي استخدام الطرق الثابتة على الأنواع:
\n\n// رقم صحيح عشوائي من 1 إلى 100\nlet randomInt = Int.random(in: 1...100)\n\n// رقم عشري عشوائي من 0.0 إلى 1.0\nlet randomDouble = Double.random(in: 0.0...1.0)\n\n// رقم Float عشوائي\nlet randomFloat = Float.random(in: 0.0...1.0)\n\n// Bool عشوائي\nlet randomBool = Bool.random()\n\n\nيستخدم هذا API المولد النظامي SystemRandomNumberGenerator، وهو مشفر (ولكن المزيد عن ذلك لاحقاً). مهم: يتم تحديد النطاق عبر closed range (...) أو half-open range (..<).
لماذا هذا رائع؟
\n- \n
- سلامة الأنواع - لن يسمح لك المترجم بتوليد Double وتعيينه إلى Int. \n
- عدم وجود انحياز - Swift يهتم بنفسه بتوحيد التوزيع. \n
- العالمية - يعمل مع جميع الأنواع الرقمية: Int, UInt, Int8, Float, Double, CGFloat وحتى Bool. \n
توليد رقم عشوائي من نطاق: المزالق
\n\nقد يبدو الأمر بسيطاً؟ لننظر إلى مثال:
\n\nlet diceRoll = Int.random(in: 1...6) // نرد: 1,2,3,4,5,6\nlet coinFlip = Int.random(in: 0..<2) // عملة: 0 أو 1\n\n\nكل شيء صحيح. ولكن إذا أردت توليد رقم عشوائي بدون حد أعلى (مثلاً، من 0 إلى ما لا نهاية) - لن ينجح ذلك. يتطلب Swift تحديد النطاق بوضوح. تم ذلك عن قصد لتجنب أخطاء التجاوز.
\n\nإذا كنت بحاجة إلى رقم عشوائي من 0 إلى max (حيث max متغير)، استخدم ببساطة:
let maxValue = 500\nlet randomUpTo = Int.random(in: 0...maxValue)\n\n\nعنصر عشوائي من مجموعة (Array, Set, Dictionary)
\n\nغالباً ما يكون توليد رقم عشوائي مطلوباً ليس بحد ذاته، بل لاختيار عنصر عشوائي. يوفر Swift حلاً أنيقاً:
\n\nlet fruits = ["تفاح", "موز", "كرز", "شمام"]\nif let randomFruit = fruits.randomElement() {\n print("اليوم نأكل \\(randomFruit)")\n} else {\n print("السلة فارغة!")\n}\n\n\nطريقة randomElement() تُرجع قيمة اختيارية - هذا مهم، لأن المجموعة قد تكون فارغة. لخلط المصفوفة بأكملها استخدم shuffled():
let shuffledFruits = fruits.shuffled()\nprint(shuffledFruits) // مثلاً: ["موز", "شمام", "تفاح", "كرز"]\n\n\nالتوليد المشفر: عندما تكون الأمان فوق كل شيء
\n\nالمولد القياسي I