【问题标题】:How does one generate a random number in Swift?如何在 Swift 中生成随机数?
【发布时间】:2014-07-23 07:32:46
【问题描述】:

我意识到 Swift 书提供了随机数生成器的实现。将此实现复制并粘贴到自己的程序中的最佳做法是什么?或者有没有我们现在可以使用的库?

【问题讨论】:

    标签: swift random


    【解决方案1】:

    我已经能够使用rand() 来获得随机CInt。您可以使用以下方法将其设为 Int:

    let myVar: Int = Int(rand())
    

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

    【讨论】:

    • 是的,否则类型转换可能是一项棘手的工作,让 Int 构造函数处理它是真正的痛苦节省。
    • 请注意,如果您在使用 rand() 之前没有调用 srand(...)(只调用一次),那么每次执行程序之间的数字序列将始终完全相同.如果你不想要这个然后使用 arc4random()
    • 你也可以使用random(),它返回一个Int而不是UInt32——就像@SomeGuy提到的那样,在使用它之前只要在任何地方调用一次srandom(arc4random())就可以确保它有一个为您的程序的每次执行提供不同的随机种子。
    • 谁能评论 rand() vs arc4random_uniform()?
    【解决方案2】:

    你可以像在 C 中那样做:

    let randomNumber = arc4random()
    

    randomNumber 被推断为 UInt32 类型(一个 32 位无符号整数)

    【讨论】:

    • 附录:randarc4randomdrand48 和朋友都在Darwin 模块中。如果您正在构建 Cocoa、UIKit 或 Foundation 应用程序,它已经为您导入,但您需要在 Playground 中 import Darwin
    • 并且不要尝试将 arc4random() 的结果转换为 Int — 这在 64 位平台上可以正常工作,但在 32 位平台上,Int 是 32 位签名的,所以你会得到意想不到的负数。这已经把一些人绊倒了,所以我想在这里提一下。
    【解决方案3】:

    Swift 4.2+

    Xcode 10 附带的 Swift 4.2 为许多数据类型引入了新的易于使用的随机函数。 您可以在数值类型上调用random() 方法。

    let randomInt = Int.random(in: 0..<6)
    let randomDouble = Double.random(in: 2.71828...3.14159)
    let randomBool = Bool.random()
    

    【讨论】:

    • 我不必显式导入 Darwin
    • 在我的 Playground 文件中,我需要导入 Darwin,因为我没有导入任何其他内容。
    • SoliQuiD: 除了省略arc4后面的额外下划线,即arc4random_uniform(5)。
    • 警告:RC4 或 arc4 has been showndistinguishable from pure random values。因此,尽管 arc4(流密码)听起来在密码学上是安全的,但实际上并非如此。
    • @MaartenBodewes:不再与这个答案直接相关,但 arc4random 实际上并没有在 macOS 或 BSD 上使用 RC4 密码,尽管它的名字。它在 macOS 上使用系统提供的 CSPRNG,在大多数 BSD 上使用 ChaCha20。 Swift 的默认 RNG(在此答案中使用)将其称为 macOS 上的实现细节,但在每个支持的平台上使用适当的底层生成器。
    【解决方案4】:

    使用 arc4random_uniform(n) 表示 0 到 n-1 之间的随机整数。

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

    将结果转换为 Int,这样您就不必将变量显式键入为 UInt32(这似乎不是 Swifty)。

    【讨论】:

    • 非常简单。我喜欢。点赞!但是实际的骰子没有0。在您的代码中,diceRoll 可能是 0。只是说...
    • 是的,你真的想要Int(arc4random_uniform(6)+1)
    • probability = Int(arc4random_uniform(UInt32(total))) - 我也必须转换成 UInt32
    • 让 randomElementInArray = Int(arc4random_uniform(array.count))
    • 如果您使用的值尚不属于该类型,请不要忘记将输入 arc3random_uniform(n) 的参数 n 转换为 UInt32(n)
    【解决方案5】:

    为 Swift 4.2 编辑

    从 Swift 4.2 开始,您现在可以使用 Swift 自己的原生函数,而不是使用导入的 C 函数 arc4random_uniform()。

    // Generates integers starting with 0 up to, and including, 10
    Int.random(in: 0 ... 10)
    

    您也可以使用random(in:) 来获取其他原始值的随机值;例如 Int、Double、Float 甚至 Bool。

    Swift 版本

    此方法将在给定的最小值和最大值之间生成一个随机的Int

    func randomInt(min: Int, max: Int) -> Int {
        return min + Int(arc4random_uniform(UInt32(max - min + 1)))
    }
    

    【讨论】:

      【解决方案6】:

      编辑: Updated for Swift 3.0

      arc4random 在 Swift 中运行良好,但基本函数仅限于 32 位整数类型(Int 在 iPhone 5S 和现代 Mac 上是 64 位)。这是一个可以用整数字面量表示的类型的随机数的通用函数:

      public func arc4random<T: ExpressibleByIntegerLiteral>(_ type: T.Type) -> T {
          var r: T = 0
          arc4random_buf(&r, MemoryLayout<T>.size)
          return r
      }
      

      我们可以使用这个新的通用函数来扩展UInt64,添加边界参数并减轻模偏差。 (这是直接从arc4random.c 提出来的)

      public extension UInt64 {
          public static func random(lower: UInt64 = min, upper: UInt64 = max) -> UInt64 {
              var m: UInt64
              let u = upper - lower
              var r = arc4random(UInt64.self)
      
              if u > UInt64(Int64.max) {
                  m = 1 + ~u
              } else {
                  m = ((max - (u * 2)) + 1) % u
              }
      
              while r < m {
                  r = arc4random(UInt64.self)
              }
      
              return (r % u) + lower
          }
      }
      

      这样我们就可以为相同的参数扩展Int64,处理溢出:

      public extension Int64 {
          public static func random(lower: Int64 = min, upper: Int64 = max) -> Int64 {
              let (s, overflow) = Int64.subtractWithOverflow(upper, lower)
              let u = overflow ? UInt64.max - UInt64(~s) : UInt64(s)
              let r = UInt64.random(upper: u)
      
              if r > UInt64(Int64.max)  {
                  return Int64(r - (UInt64(~lower) + 1))
              } else {
                  return Int64(r) + lower
              }
          }
      }
      

      为了完整的家庭......

      private let _wordSize = __WORDSIZE
      
      public extension UInt32 {
          public static func random(lower: UInt32 = min, upper: UInt32 = max) -> UInt32 {
              return arc4random_uniform(upper - lower) + lower
          }
      }
      
      public extension Int32 {
          public static func random(lower: Int32 = min, upper: Int32 = max) -> Int32 {
              let r = arc4random_uniform(UInt32(Int64(upper) - Int64(lower)))
              return Int32(Int64(r) + Int64(lower))
          }
      }
      
      public extension UInt {
          public static func random(lower: UInt = min, upper: UInt = max) -> UInt {
              switch (_wordSize) {
                  case 32: return UInt(UInt32.random(UInt32(lower), upper: UInt32(upper)))
                  case 64: return UInt(UInt64.random(UInt64(lower), upper: UInt64(upper)))
                  default: return lower
              }
          }
      }
      
      public extension Int {
          public static func random(lower: Int = min, upper: Int = max) -> Int {
              switch (_wordSize) {
                  case 32: return Int(Int32.random(Int32(lower), upper: Int32(upper)))
                  case 64: return Int(Int64.random(Int64(lower), upper: Int64(upper)))
                  default: return lower
              }
          }
      }
      

      毕竟,我们终于可以做这样的事情了:

      let diceRoll = UInt64.random(lower: 1, upper: 7)
      

      【讨论】:

      • 无法编译:var r = arc4random(UInt64)。请指教你的意思是什么?
      • @Ossir 对我来说编译得很好......这意味着使用参数 UInt64 调用函数 arc4random(在第一个代码块中定义)这是一个 Type
      • arc4random_buf(以及所有 64 位扩展)是否存在模偏差?
      • 模数偏差仅在您添加上限时起作用,因此不适用于arc4random_buf。这些扩展的目的是完全按照 arc4random_uniform 所做的(减轻模偏差),除了 64 位类型。
      • 使用浮点函数时,如何将上限值包含在可能性范围内?因此,假设我将 0.0 作为下限,将 1.0 作为上限。有了这个逻辑,它会给我 0.0 到 0.99999999。但相反,我想将 1.0 包括在内。我怎样才能做到这一点?
      【解决方案7】:

      我使用了这个代码:

      var k: Int = random() % 10;
      

      【讨论】:

      • 你必须先调用srandom(UInt32(time(nil))),否则总是返回相同的数列
      • 我在 random() 上阅读了苹果文档两次,但无法收集它的用法......我希望他们只是在上面包含了一个简单的代码示例。 “random() 函数使用非线性、加性反馈、随机数生成器,使用大小为 31 个长整数的默认表。它返回 0 到 (231) 范围内的连续伪随机数- 1.这个随机数发生器的周期很大,大约16*((231)-1)。" ...非常感谢苹果...我一定会在我的下一篇论文中引用这个。
      • random() 有时会导致 iPad 突然崩溃。如果发生这种情况,请使用上面的 arc4random_uniform(6)。如果您使用 random(),那么您可以通过添加 srandomdev() 来创建更多随机值。
      • 我收到编译器错误消息:random is unavailable in Swift: Use arc4random instead.
      • 这个解决方案有模偏差:zuttobenkyou.wordpress.com/2012/10/18/…
      【解决方案8】:
      var randomNumber = Int(arc4random_uniform(UInt32(5)))
      

      这里的 5 会确保随机数是从零到四生成的。您可以相应地设置该值。

      【讨论】:

      • 如果您通过 5,它将返回从零到四的 5 个可能结果。 0...4
      【解决方案9】:

      你可以像这样使用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())
      

      【讨论】:

      • 斐波那契随机数如何?
      • 嗨 Nikolai,这个代码块是旧版本的 Swift 1.2。如果你尝试新的 Swift 2.0.它不会起作用。
      • 我明白,但在我看来,它仍然像一个斐波那契生成器,而不是问题中要求的随机数。
      【解决方案10】:

      我想在现有答案中补充一点,Swift 书中的随机数生成器示例是一个线性同余生成器 (LCG),它是一个严重受限的示例,除了必须是微不足道的示例,其中质量随机性根本不重要。 不得将 LCG 用于加密目的

      arc4random() 要好得多,可用于大多数用途,但同样不应用于加密用途。

      如果您想要保证加密安全的东西,请使用SecCopyRandomBytes()。请注意,如果您将随机数生成器构建到某个东西中,其他人可能最终会(错误)将其用于加密目的(例如密码、密钥或盐生成),那么您无论如何都应该考虑使用 SecCopyRandomBytes(),即使您的需要并不完全需要。

      【讨论】:

        【解决方案11】:

        从 iOS 9 开始,您可以使用新的 GameplayKit 类以多种方式生成随机数。

        您有四种源类型可供选择:一般随机源(未命名,由系统选择其功能)、线性同余、ARC4 和 Mersenne Twister。这些可以生成随机整数、浮点数和布尔值。

        在最简单的层面上,您可以像这样从系统内置的随机源生成一个随机数:

        GKRandomSource.sharedRandom().nextInt()
        

        这会生成一个介于 -2,147,483,648 和 2,147,483,647 之间的数字。如果您想要一个介于 0 和上限(不包括)之间的数字,您可以使用:

        GKRandomSource.sharedRandom().nextIntWithUpperBound(6)
        

        GameplayKit 内置了一些方便的构造函数来处理骰子。例如,您可以像这样掷六面骰子:

        let d6 = GKRandomDistribution.d6()
        d6.nextInt()
        

        此外,您还可以使用 GKShuffledDistribution 之类的东西来塑造随机分布。这需要更多解释,但如果您有兴趣,可以read my tutorial on GameplayKit random numbers

        【讨论】:

        • 感谢您的提示,这是最好的答案之一。要使用这些功能,需要添加import GameplayKit。 Swift 3 将语法改为GKRandomSource.sharedRandom().nextInt(upperBound: 6)
        • 这个套件要导入多少重量?我不想让我的代码膨胀。
        【解决方案12】:

        使用arc4random_uniform()

        用法:

        arc4random_uniform(someNumber: UInt32) -&gt; UInt32

        这会为您提供0someNumber - 1 范围内的随机整数。

        UInt32 的最大值为 4,294,967,295(即2^32 - 1)。

        示例:

        • 抛硬币

            let flip = arc4random_uniform(2) // 0 or 1
          
        • 掷骰子

            let roll = arc4random_uniform(6) + 1 // 1...6
          
        • 10 月的随机一天

            let day = arc4random_uniform(31) + 1 // 1...31
          
        • 1990 年代的随机年份

            let year = 1990 + arc4random_uniform(10)
          

        一般形式:

        let number = min + arc4random_uniform(max - min + 1)
        

        其中numbermaxminUInt32

        怎么样...

        arc4random()

        您还可以使用arc4random() 获得一个随机数,这会产生介于0 和2^32-1 之间的UInt32。因此,要获得0x-1 之间的随机数,您可以将其除以x 并取余数。或者换句话说,使用Remainder Operator (%):

        let number = arc4random() % 5 // 0...4
        

        但是,这会产生轻微的modulo bias(另请参阅herehere),因此建议使用arc4random_uniform()

        Int相互转换

        通常,为了在IntUInt32 之间来回转换,可以这样做:

        let number: Int = 10
        let random = Int(arc4random_uniform(UInt32(number)))
        

        但问题在于,Int 在 32 位系统上的范围为 -2,147,483,648...2,147,483,647,而在 64 位系统上的范围为 -9,223,372,036,854,775,808...9,223,372,036,854,775,807。将此与0...4,294,967,295UInt32 范围进行比较。 UInt32U 表示 未签名

        考虑以下错误:

        UInt32(-1) // negative numbers cause integer overflow error
        UInt32(4294967296) // numbers greater than 4,294,967,295 cause integer overflow error
        

        因此,您只需确保输入参数在UInt32 范围内,并且您也不需要超出该范围的输出。

        【讨论】:

          【解决方案13】:

          这是一个做得很好的库 https://github.com/thellimist/SwiftRandom

          public extension Int {
              /// SwiftRandom extension
              public static func random(lower: Int = 0, _ upper: Int = 100) -> Int {
                  return lower + Int(arc4random_uniform(UInt32(upper - lower + 1)))
              }
          }
          
          public extension Double {
              /// SwiftRandom extension
              public static func random(lower: Double = 0, _ upper: Double = 100) -> Double {
                  return (Double(arc4random()) / 0xFFFFFFFF) * (upper - lower) + lower
              }
          }
          
          public extension Float {
              /// SwiftRandom extension
              public static func random(lower: Float = 0, _ upper: Float = 100) -> Float {
                  return (Float(arc4random()) / 0xFFFFFFFF) * (upper - lower) + lower
              }
          }
          
          public extension CGFloat {
              /// SwiftRandom extension
              public static func random(lower: CGFloat = 0, _ upper: CGFloat = 1) -> CGFloat {
                  return CGFloat(Float(arc4random()) / Float(UINT32_MAX)) * (upper - lower) + lower
              }
          }
          

          【讨论】:

            【解决方案14】:

            在某些版本的 Xcode 中没有 arc4Random_uniform()(在 7.1 中它可以运行,但不会自动完成)。您可以改为这样做。

            生成一个 0-5 的随机数。 首先

            import GameplayKit
            

            然后

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

            【讨论】:

              【解决方案15】:

              10(0-9)之间的随机数示例;

              import UIKit
              
              let randomNumber = Int(arc4random_uniform(10))
              

              非常简单的代码 - 简单而简短。

              【讨论】:

                【解决方案16】:
                 let MAX : UInt32 = 9
                 let MIN : UInt32 = 1
                
                    func randomNumber()
                {
                    var random_number = Int(arc4random_uniform(MAX) + MIN)
                    print ("random = ", random_number);
                }
                

                【讨论】:

                  【解决方案17】:

                  我用这段代码生成一个随机数:

                  //
                  //  FactModel.swift
                  //  Collection
                  //
                  //  Created by Ahmadreza Shamimi on 6/11/16.
                  //  Copyright © 2016 Ahmadreza Shamimi. All rights reserved.
                  //
                  
                  import GameKit
                  
                  struct FactModel {
                  
                      let fun  = ["I love swift","My name is Ahmadreza","I love coding" ,"I love PHP","My name is ALireza","I love Coding too"]
                  
                  
                      func getRandomNumber() -> String {
                  
                          let randomNumber  = GKRandomSource.sharedRandom().nextIntWithUpperBound(fun.count)
                  
                          return fun[randomNumber]
                      }
                  }
                  

                  【讨论】:

                  • 欢迎来到 SO。不鼓励仅使用代码回答 - 请编辑您的回答以解释此代码回答问题的原因以及它是如何工作的。有关更多信息,请参阅 stackoverflow.com/help/how-to-answer。
                  • 请围绕您的答案提供一些上下文,并欢迎使用 stackoverflow。 :)
                  【解决方案18】:

                  以下代码将产生一个介于 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) }
                    }
                  }
                  

                  这些方法使用一个额外的随机数来确定将使用多少个UInt8s 来创建随机数。最后一行将[UInt8] 转换为UInt16UInt32

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

                  【讨论】:

                  • 您巧妙地避免了模数引入的偏差,为此加了 1。您可能会警告读者您为什么这样做。
                  • 这很有趣,我并没有真正考虑到模偏差可能在这里起作用。可能获得少量数字的机会与获得大量数字的机会不同。
                  【解决方案19】:

                  @jstn's answer 很好,但有点冗长。 Swift 被称为面向协议的语言,因此我们可以通过为协议扩展添加默认实现来实现相同的结果,而无需为整数系列中的每个类实现样板代码。

                  public extension ExpressibleByIntegerLiteral {
                      public static func arc4random() -> Self {
                          var r: Self = 0
                          arc4random_buf(&r, MemoryLayout<Self>.size)
                          return r
                      }
                  }
                  

                  现在我们可以这样做了:

                  let i = Int.arc4random()
                  let j = UInt32.arc4random()
                  

                  所有其他整数类都可以。

                  【讨论】:

                    【解决方案20】:

                    详情

                    xCode 9.1,斯威夫特 4

                    面向数学的解决方案 (1)

                    import Foundation
                    
                    class Random {
                    
                        subscript<T>(_ min: T, _ max: T) -> T where T : BinaryInteger {
                            get {
                                return rand(min-1, max+1)
                            }
                        }
                    }
                    
                    let rand = Random()
                    
                    func rand<T>(_ min: T, _ max: T) -> T where T : BinaryInteger {
                        let _min = min + 1
                        let difference = max - _min
                        return T(arc4random_uniform(UInt32(difference))) + _min
                    }
                    

                    解决方案的使用(一)

                    let x = rand(-5, 5)       // x = [-4, -3, -2, -1, 0, 1, 2, 3, 4]
                    let x = rand[0, 10]       // x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
                    

                    面向程序员的解决方案(二)

                    不要忘记在此处添加面向数学的解决方案 (1) 代码

                    import Foundation
                    
                    extension CountableRange where Bound : BinaryInteger {
                    
                        var random: Bound {
                            return rand(lowerBound-1, upperBound)
                        }
                    }
                    
                    extension CountableClosedRange where Bound : BinaryInteger {
                    
                        var random: Bound {
                            return rand[lowerBound, upperBound]
                        }
                    }
                    

                    解决方案的使用(二)

                    let x = (-8..<2).random           // x = [-8, -7, -6, -5, -4, -3, -2, -1, 0, 1]
                    let x = (0..<10).random           // x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
                    let x = (-10 ... -2).random       // x = [-10, -9, -8, -7, -6, -5, -4, -3, -2]
                    

                    完整样本

                    不要忘记在此处添加解决方案(1)和解决方案(2)代码

                    private func generateRandNums(closure:()->(Int)) {
                    
                        var allNums = Set<Int>()
                        for _ in 0..<100 {
                            allNums.insert(closure())
                        }
                        print(allNums.sorted{ $0 < $1 })
                    }
                    
                    generateRandNums {
                        (-8..<2).random
                    }
                    
                    generateRandNums {
                        (0..<10).random
                    }
                    
                    generateRandNums {
                        (-10 ... -2).random
                    }
                    
                    generateRandNums {
                        rand(-5, 5)
                    }
                    generateRandNums {
                        rand[0, 10]
                    }
                    

                    样本结果

                    【讨论】:

                    • 这个答案离题了。问题是如何生成随机数。不是如何制作随机数库。嘘。
                    【解决方案21】:

                    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)
                    

                    【讨论】:

                      【解决方案22】:

                      Swift 4.2

                      有一组新的 API:

                      let randomIntFrom0To10 = Int.random(in: 0 ..< 10)
                      let randomDouble = Double.random(in: 1 ... 10)
                      
                      • 所有 numeric 类型现在都具有采用 rangerandom(in:) 方法。

                      • 它返回一个均匀分布在该范围内的数字。


                      TL;DR

                      那么,“好”的旧方法有什么问题?

                      1. 您必须使用导入的C API(它们在平台之间有所不同)

                      2. 而且……

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

                      如果您像arc4random() % aNumber 一样使用arc4random() (计算余数),则结果不会均匀分布在0aNumber 之间。有一个称为模数偏差的问题。

                      模偏差

                      通常,该函数会在0MAX (取决于类型等)之间生成一个随机数。举一个简单的例子,假设最大数是7,并且您关心0 ..&lt; 2范围内的随机数(如果您愿意,也可以是区间 [0, 3)).

                      个别数字的概率是:

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

                      换句话说,与 2 相比,您更有可能01 结束。 当然,请记住,这是非常简化的,并且 MAX 数字要高得多,使其更加“公平”。

                      Swift 4.2

                      中的SE-0202 - Random unification 解决了这个问题

                      【讨论】:

                        【解决方案23】:

                        斯威夫特 4.2

                        Swift 4.2 在标准库中包含了一个原生且功能相当全面的随机数 API。 (Swift Evolution proposal SE-0202)

                        let intBetween0to9 = Int.random(in: 0...9) 
                        let doubleBetween0to1 = Double.random(in: 0...1)
                        

                        所有数字类型都有静态random(in:),它接受范围并返回给定范围内的随机数

                        【讨论】:

                          【解决方案24】:

                          更新:2021 年 10 月 1 日。

                          斯威夫特 5.5

                          假设我们有一个数组:

                          let numbers: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
                          


                          对于 iOS 和 macOS,您可以在 Xcode 的框架 GameKit 中使用系统范围的随机源。在这里你可以找到GKRandomSource 类及其sharedRandom() 类方法:

                          import GameKit
                          
                          private func randomNumberGenerator() -> Int {
                              let random = GKRandomSource.sharedRandom().nextInt(upperBound: numbers.count)
                              return numbers[random]
                          }
                          
                          randomNumberGenerator()
                          


                          您还可以使用返回集合的随机元素的randomElement() 方法:

                          let randomNumber = numbers.randomElement()!
                          print(randomNumber)
                          


                          或使用arc4random_uniform()。注意这个方法返回的是UInt32

                          let generator = Int(arc4random_uniform(10))
                          print(generator)
                          


                          当然,我们可以使用makeIterator() 方法,该方法返回集合元素的迭代器。

                          let iterator: Int = (1...10).makeIterator().shuffled().first!
                          print(iterator)
                          


                          您在此处看到的最后一个示例在static func random(in range: ClosedRange&lt;Int&gt;) -&gt; Int 的帮助下返回指定范围内的随机值。

                          let randomizer = Int.random(in: 1...10)
                          print(randomizer)
                          

                          【讨论】:

                            【解决方案25】:

                            斯威夫特 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()
                            
                            1. 您使用 random(in:) 从范围中生成随机数字。
                            2. randomElement() 如果范围为空则返回 nil,所以你解开返回的 Int?如果让。
                            3. 您使用 random(in:) 生成随机 Double、Float 或 CGFloat 并使用 random() 返回随机 Bool。

                            More @ Official

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              相关资源
                              最近更新 更多