I have researched and looked into many different random function, but the downside to them is that they only work for one data type. I want a way to have one function work for a Double, Floats, Int, CGFloat, etc. I know I could just convert it to different data types, but I would like to know if there is a way to have it done using generics. Does someone know a way to make a generic random function using swift. Thanks.
In theory you could port code such as this answer (which is not necessarily a great solution, depending on your needs, since UInt32.max
is relatively small)
extension FloatingPointType {
static func rand() -> Self {
let num = Self(arc4random())
let denom = Self(UInt32.max)
// this line won’t compile:
return num / denom
}
}
// then you could do
let d = Double.rand()
let f = Float.rand()
let c = CGFloat.rand()
Except… FloatingPointType
doesn’t conform to a protocol that guarantees operators like /
, +
etc (unlike IntegerType
which conforms to _IntegerArithmeticType
).
You could do this manually though:
protocol FloatingPointArithmeticType: FloatingPointType {
func /(lhs: Self, rhs: Self) -> Self
// etc
}
extension Double: FloatingPointArithmeticType { }
extension Float: FloatingPointArithmeticType { }
extension CGFloat: FloatingPointArithmeticType { }
extension FloatingPointArithmeticType {
static func rand() -> Self {
// same as before
}
}
// so these now work
let d = Double.rand() // etc
but this probably isn’t quite as out-of-the-box as you were hoping (and no doubt contains some subtle invalid assumption about floating-point numbers on my part).
As for something that works across both integers and floats, the Swift team have mentioned on their mail groups before that the lack of protocols spanning both types is a conscious decision since it’s rarely correct to write the same code for both, and that’s certainly the case for generating random numbers, which need two very different approaches.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With