I'm going through the first chapter of The Swift Programming Language
book and I'm at the part where it's describing the extension
keyword.
I had a go at the "Experiment":
“Write an extension for the Double type that adds an absoluteValue property.”
I got it working like this:
extension Double {
var absoluteValue: Double {
if(self < 0) {
return self * -1
}
return self
}
}
(-10.5).absoluteValue // 10.5
But it also seems to work for integers:
(-4).absoluteValue // 4.0
What is happening here? Is the compiler changing the type from Int
to Double
because it sees that there is a absoluteValue
extension on Double
but not Int
?
This appears to be the case because if I add another extension
of the same name on Int
like so:
extension Int {
var absoluteValue: Int {
return 42
}
}
That overrides the extension
on Double
. And (-4).absoluteValue
returns 42
Is there a way to add an extension
that only works on Double
s but not Int
s?
Edit: Looks like it's doing a conversion at compile-time and since I didn't define a type for my literal it converted it. The following produces an error
var i:Int = -4;
i.absoluteValue
"Playground execution failed: error: :12:1: error: 'Int' does not have a member named 'absoluteValue' i.absoluteValue ^ ~~~~~~~~~~~~~"
Edit 2: It appears to only apply to literals; the following also produces an error:
var i = -4;
i.absoluteValue
Yes, the extension you wrote is actually only for Double
s, not for Int
s. Take a look at this example:
extension Double {
var absoluteValue: Double {
if (self < 0) {
return self * -1
}
return self
}
}
var double: Int = 10
double.absoluteValue // Int does not have a member named absoluteValue
But, in your code the compiler is implicitly converting your Int
to a Double
.
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