Reputation: 22252
Let's say for academic purposes, I would prefer an expression like
someInt.asDouble
rather than the stock
Double(someInt)
Since all of the various Swift integer types conform to the IntegerType
protocol AND because there seems to be a Double()
initializer that fits every kind of those int types, I thought I could something like:
extension IntegerType {
var asDouble:Double {
return Double(self)
}
}
This does not work. And I would like to know why? I would like to know if there is some magic that would make it work? A where
maybe? Or something to do with the self
reference?
The error I get in the console of the playground I tried in this reads:
Playground execution failed: /var/folders/2k/6y8rslzn1m95gjpg534j7v8jzr03tz/T/./lldb/41416/playground37.swift:31:10: error: cannot invoke initializer for type 'Double' with an argument list of type '(Self)'
return Double(self)
^
/var/folders/2k/6y8rslzn1m95gjpg534j7v8jzr03tz/T/./lldb/41416/playground37.swift:31:10: note: overloads for 'Double' exist with these partially matching parameter lists: (Double), (UInt8), (Int8), (UInt16), (Int16), (UInt32), (Int32), (UInt64), (Int64), (UInt), (Int), (Float), (Float80), (String), (CGFloat), (NSNumber)
return Double(self)
Upvotes: 2
Views: 185
Reputation: 299275
All IntegerType
types can be promoted to IntMax
, and IntMax
can be converted to Double
.
extension IntegerType {
var asDouble: Double {
return Double(self.toIntMax())
}
}
As you suggest, this is not a particularly useful thing to do (Double(x)
is the correct syntax), but it may be useful for other problems.
I would continue stdlib's pattern if I were going to create this. The pattern is toX()
rather than asX
:
extension IntegerType {
func toDouble() -> Double {
return Double(self.toIntMax())
}
}
See also toOpaque()
and toUIntMax()
. as
suggests a simple reinterpretation of the type without copying, and a var
suggests that it's a property of this value. That's not what's happening. You're actually converting it to a different value, stored in a different format, that may not even be equal. (For large integers, there may be rounding errors such that x != Int(x.toDouble())
.)
It's worth also reading Trying to extend IntegerType (and FloatingPointType); Why can't all Int types be converted to NSTimeInterval, which discusses the problem further, along with why similar features can be dangerous unless done with great care.
Upvotes: 3