Swift et les nombres aléatoires : une magie qui fonctionne de manière prévisible
\n\nTout développeur rencontre tôt ou tard le problème : « Comment générer un nombre aléatoire ? ». Rien de plus simple, semble-t-il. Mais dans le monde de Swift, ce sujet a parcouru un long chemin d'évolution — des anciennes fonctions C à l'API intégrée élégante. Dans cet article, nous allons passer en revue toutes les méthodes de génération de nombres aléatoires en Swift, des plus simples aux plus professionnelles, avec des exemples concrets et des nuances importantes.
\n\nSi vous vous êtes déjà demandé pourquoi votre arc4random() renvoie des nombres étranges ou comment faire un véritable choix aléatoire dans un tableau — vous êtes au bon endroit. C'est parti !
Bref historique : comment en sommes-nous arrivés là
\n\nAvant Swift 4.2 (2018), les développeurs devaient choisir péniblement entre arc4random(), drand48() et des solutions de fortune comme rand() % 100. Cette dernière était d'ailleurs dangereuse — un biais dans la distribution était garanti si la plage n'était pas divisible par RAND_MAX. Avec la sortie de Swift 4.2, Apple nous a offert le protocole RandomNumberGenerator et des méthodes intégrées. Désormais, la génération de nombres aléatoires est devenue sûre, lisible et uniforme.
La méthode moderne : RandomNumberGenerator et méthodes de types
\n\nDepuis Swift 4.2, la manière la plus correcte et la plus simple consiste à utiliser les méthodes statiques sur les types :
\n\n// Nombre entier aléatoire de 1 à 100\nlet randomInt = Int.random(in: 1...100)\n\n// Nombre à virgule flottante aléatoire de 0.0 à 1.0\nlet randomDouble = Double.random(in: 0.0...1.0)\n\n// Nombre Float aléatoire\nlet randomFloat = Float.random(in: 0.0...1.0)\n\n// Booléen aléatoire\nlet randomBool = Bool.random()\n\n\nCette API utilise le générateur système SystemRandomNumberGenerator, qui est cryptographique (mais nous y reviendrons). Important : la plage est définie via un intervalle fermé (...) ou un intervalle semi-ouvert (..<).
Pourquoi est-ce génial ?
\n- \n
- Sécurité des types — le compilateur ne vous permettra pas de générer un Double et de l'affecter à un Int. \n
- Absence de biais — Swift se charge lui-même de l'uniformité de la distribution. \n
- Universalité — fonctionne pour tous les types numériques : Int, UInt, Int8, Float, Double, CGFloat et même Bool. \n
Génération d'un nombre aléatoire dans une plage : pièges à éviter
\n\nQue pourrait-il mal se passer, semble-t-il ? Prenons un exemple :
\n\nlet diceRoll = Int.random(in: 1...6) // Dé : 1,2,3,4,5,6\nlet coinFlip = Int.random(in: 0..<2) // Pièce : 0 ou 1\n\n\nTout est correct. Mais si vous voulez générer un nombre aléatoire sans limite supérieure (par exemple, de 0 à l'infini) — ce n'est pas possible. Swift exige une plage explicite. Cela a été fait exprès pour éviter les erreurs de débordement.
\n\nSi vous avez besoin d'un nombre aléatoire de 0 à max (où max est une variable), utilisez simplement :
let maxValue = 500\nlet randomUpTo = Int.random(in: 0...maxValue)\n\n\nÉlément aléatoire d'une collection (Array, Set, Dictionary)
\n\nLa génération d'un nombre aléatoire est souvent nécessaire non pas en soi, mais pour choisir un élément aléatoire. Swift offre une solution élégante :
\n\nlet fruits = ["pomme", "banane", "cerise", "melon"]\nif let randomFruit = fruits.randomElement() {\n print("Aujourd'hui, on mange \\(randomFruit)")\n} else {\n print("Le panier est vide !")\n}\n\n\nLa méthode randomElement() renvoie une valeur optionnelle — c'est important, car la collection peut être vide. Pour mélanger l'ensemble du tableau, utilisez shuffled() :
let shuffledFruits = fruits.shuffled()\nprint(shuffledFruits) // par exemple : ["banane", "melon", "pomme", "cerise"]\n\n\nGénération cryptographique : quand la sécurité est primordiale
\n\nLe I