我意识到Swift书籍提供了一个随机数生成器的实现。复制和粘贴这个实现是最佳实践吗?或者有没有这样的库,我们现在就可以使用?


当前回答

在某些版本的Xcode中没有arc4Random_uniform()(在7.1中运行,但对我来说不自动完成)。你可以这样做。

从0-5中生成一个随机数。 第一个

import GameplayKit

Then

let diceRoll = GKRandomSource.sharedRandom().nextIntWithUpperBound(6)

其他回答

对于0到n-1之间的随机整数,使用arc4random_uniform(n)。

let diceRoll = Int(arc4random_uniform(6) + 1)

将结果转换为Int,这样你就不必显式地将你的vars类型为UInt32(这看起来不像swifty)。

我已经能够使用rand()来获得一个随机的CInt。你可以使用这样的方法使它成为Int型:

let myVar: Int = Int(rand())

你可以使用你最喜欢的C随机函数,并在需要时将值转换为Int。

从Swift 4.2开始

有一组新的api:

let randomIntFrom0To10 = Int.random(in: 0 ..< 10)
let randomDouble = Double.random(in: 1 ... 10)

所有数字类型现在都有random(in:)方法,该方法接受range。 它返回一个在该范围内均匀分布的数字。


博士TL;

那么,“好”的旧方法有什么错呢?

你必须使用导入的C api(它们在不同平台之间是不同的)。 而且……

如果我告诉你随机并不是那么随机呢?

如果您使用arc4random()(计算余数),如arc4random() % aNumber,结果不是均匀分布在0和aNumber之间。有一个问题叫做模偏倚。

模的偏见

通常,该函数生成一个0到MAX之间的随机数(取决于类型等)。举个简单的例子,假设最大的数字是7,你关心的是一个范围为0 ..< 2(或者间隔[0,3),如果你喜欢的话)。

单个数字的概率为:

0: 3/8 = 37.5% 1: 3/8 = 37.5% 2: 2/8 = 25%

换句话说,你更有可能得到0或1而不是2。 当然,请记住,这是非常简化的,MAX数字要高得多,使其更加“公平”。

Swift 4.2中的SE-0202 -随机统一解决了这个问题

你可以像这样使用GeneratorOf:

var fibs = ArraySlice([1, 1])
var fibGenerator = GeneratorOf{
    _ -> Int? in
    fibs.append(fibs.reduce(0, combine:+))
    return fibs.removeAtIndex(0)
}

println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
var randomNumber = Int(arc4random_uniform(UInt32(5)))

这里5将确保随机数是从0到4生成的。您可以设置相应的值。