Swift中的随机数生成:从random()到GameplayKit

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Swift与随机数:可预测的魔法

\n\n

每位开发者迟早都会遇到这样一个问题:“如何生成一个随机数?”看起来很简单,对吧?但在Swift的世界里,这个话题经历了一段漫长的演变——从古老的C语言函数到优雅的内置API。在本文中,我们将探讨Swift中生成随机数的所有方法,从简单到工业级,附带实际示例和重要细节。

\n\n

如果你曾经疑惑为什么你的arc4random()会返回奇怪的数字,或者如何从数组中真正随机选择一个元素——那你来对地方了。我们开始吧!

\n\n

简史:我们是如何走到这一步的

\n\n

在Swift 4.2(2018年)之前,开发者们痛苦地在arc4random()、drand48()和像rand() % 100这样的临时方案之间做选择。顺便说一句,后者很危险——如果范围不能被RAND_MAX整除,分布偏差(bias)是必然的。随着Swift 4.2的发布,Apple为我们带来了RandomNumberGenerator协议和内置方法。现在,随机数生成变得安全、可读且统一。

\n\n

现代方法: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,它是加密安全的(稍后会详细说明)。重要:范围通过闭区间(...)或半开区间(..<)指定。

\n\n

为什么这很酷?

\n
    \n
  • 类型安全——编译器不会让你生成一个Double却赋值给Int。
  • \n
  • 无偏差——Swift自动确保均匀分布。
  • \n
  • 通用性——适用于所有数值类型:Int、UInt、Int8、Float、Double、CGFloat甚至Bool。
  • \n
\n\n

从范围生成随机数:常见陷阱

\n\n

看起来,能出什么问题呢?来看一个例子:

\n\n
let 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是一个变量)的随机数,只需使用:

\n\n
let maxValue = 500\nlet randomUpTo = Int.random(in: 0...maxValue)\n
\n\n

从集合中随机选取元素(Array、Set、Dictionary)

\n\n

生成随机数本身往往不是目的,而是为了选择一个随机元素。Swift提供了一个优雅的解决方案:

\n\n
let fruits = ["苹果", "香蕉", "樱桃", "甜瓜"]\nif let randomFruit = fruits.randomElement() {\n    print("今天吃 \\(randomFruit)")\n} else {\n    print("篮子空了!")\n}\n
\n\n

randomElement()方法返回一个可选值——这很重要,因为集合可能为空。要打乱整个数组,请使用shuffled():

\n\n
let shuffledFruits = fruits.shuffled()\nprint(shuffledFruits) // 例如:["香蕉", "甜瓜", "苹果", "樱桃"]\n
\n\n

加密安全生成:当安全高于一切

\n\n

标准的I

博客

书籍推荐