这是我的示例代码
import Foundation // ar4random_uniform
extension CollectionType where Self.Index.Distance == Int {
var randomElement: Self.Generator.Element? {
if !isEmpty {
let i = Int(arc4random_uniform(UInt32(count)))
return self[startIndex.advancedBy(i)]
} else {
return nil
}
}
}
let arr = ["alfa", "beta","gama"]
let view = "abcdefghijklmnopqrstuvwxyz".characters
let dict:Dictionary<Int,Any> = [1:"a",2:true,3:1]
let range = Range<Int>(start: -99, end: 100)
let b = UnsafeMutablePointer<Int>.alloc(10)
for i in 0..<10 { (b+i).memory = 1000*i }
let buff = UnsafeMutableBufferPointer<Int>(start: b, count: 10)
for i in 0...10 {
print(arr.randomElement!,
view.randomElement!,
dict.randomElement!,
range.randomElement!,
buff.randomElement!)
}
/*
gama z (1, "a") 62 2000
alfa i (1, "a") 4 9000
alfa f (1, "a") 14 6000
gama g (1, "a") 68 8000
beta a (2, true) 42 7000
alfa y (1, "a") -76 1000
alfa i (1, "a") 76 4000
gama f (2, true) 79 3000
beta s (2, true) 46 3000
beta l (1, "a") -17 9000
gama q (3, 1) 62 9000
*/
代码按预期工作。
问题是,Swift的内置类型符合CollectionType协议,其中Self.Index.Distance != Int
以及如何在这种情况下实现相同的行为?
答案 0 :(得分:2)
typealias Distance : _SignedIntegerType = Int
因此每个Index.Distance
必须符合_SignedIntegerType
。每个_SignedIntegerType
都承诺转换为IntMax
(最宽的可用整数):
init(_: IntMax)
func toIntMax() -> IntMax
将这两个事实放在一起,我们可以计算一个随机索引(最多2个 31 -1个元素;对于大于此的集合,这会崩溃):
let randomDistance = Index.Distance(arc4random_uniform(UInt32(count.toIntMax())).toIntMax())
let randomIndex = startIndex.advancedBy(randomDistance)
return self[randomIndex]