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


当前回答

Xcode 14, swift 5

public extension Array where Element == Int {
    static func generateNonRepeatedRandom(size: Int) -> [Int] {
        guard size > 0 else {
            return [Int]()
        }
        return Array(0..<size).shuffled()
    }
}

使用方法:

let array = Array.generateNonRepeatedRandom(size: 15)
print(array)

输出

其他回答

在Swift 4.2中,您可以通过调用random()方法在任何您想要的数字类型上生成随机数,提供您想要使用的范围。例如,这会生成一个范围为1到9的随机数,两边都包括在内

let randInt = Int.random(in: 1..<10)

其他类型也一样

let randFloat = Float.random(in: 1..<20)
let randDouble = Double.random(in: 1...30)
let randCGFloat = CGFloat.random(in: 1...40)

斯威夫特4.2

拜拜导入Foundation C库arc4random_uniform()

// 1  
let digit = Int.random(in: 0..<10)

// 2
if let anotherDigit = (0..<10).randomElement() {
  print(anotherDigit)
} else {
  print("Empty range.")
}

// 3
let double = Double.random(in: 0..<1)
let float = Float.random(in: 0..<1)
let cgFloat = CGFloat.random(in: 0..<1)
let bool = Bool.random()

使用random(in:)从范围中生成随机数字。 randomElement()返回nil如果范围是空的,所以你打开返回的Int?用if let。 使用random(in:)生成随机Double、Float或CGFloat,使用random()返回随机Bool类型。

更多@官方

 let MAX : UInt32 = 9
 let MIN : UInt32 = 1

    func randomNumber()
{
    var random_number = Int(arc4random_uniform(MAX) + MIN)
    print ("random = ", random_number);
}

Xcode 14, swift 5

public extension Array where Element == Int {
    static func generateNonRepeatedRandom(size: Int) -> [Int] {
        guard size > 0 else {
            return [Int]()
        }
        return Array(0..<size).shuffled()
    }
}

使用方法:

let array = Array.generateNonRepeatedRandom(size: 15)
print(array)

输出

下面的代码将产生一个0到255之间的安全随机数:

extension UInt8 {
  public static var random: UInt8 {
    var number: UInt8 = 0
    _ = SecRandomCopyBytes(kSecRandomDefault, 1, &number)
    return number
  }
}

你这样称呼它:

print(UInt8.random)

对于更大的数字,它会变得更复杂。 这是我能想到的最好的:

extension UInt16 {
  public static var random: UInt16 {
    let count = Int(UInt8.random % 2) + 1
    var numbers = [UInt8](repeating: 0, count: 2)
    _ = SecRandomCopyBytes(kSecRandomDefault, count, &numbers)
    return numbers.reversed().reduce(0) { $0 << 8 + UInt16($1) }
  }
}

extension UInt32 {
  public static var random: UInt32 {
    let count = Int(UInt8.random % 4) + 1
    var numbers = [UInt8](repeating: 0, count: 4)
    _ = SecRandomCopyBytes(kSecRandomDefault, count, &numbers)
    return numbers.reversed().reduce(0) { $0 << 8 + UInt32($1) }
  }
}

这些方法使用一个额外的随机数来确定有多少uint8将被用于创建随机数。最后一行将[UInt8]转换为UInt16或UInt32。

我不知道后两个是否还算真正的随机,但你可以根据自己的喜好进行调整:)