Playing with the sample code from Swift Language Guide: Extensions I've extedned struct Double like this
extension Double {
func someFunc() {
print("someFunc")
}
}
I was surprised that this statement
2.someFunc()
did not generate compile time error like: Value of type 'Int' has no member 'someFunc'. I've expected value of 2 to be implicitly casted to Int but Swift casted it to Double. Why is that ? How does Swift determine that value of 2 in this case is of type Double ?
Then I've tried calling someFunc() like that
let x = 2
x.someFunc()
Here I get the expected compile time error
Does'n this contradict statement in Swift Programming Language 3.0.1 : Language guide : The basics : Type Safety and Type Inference?
Type inference enables a compiler to deduce the type of a particular expression automatically when it compiles your code, simply by examining the values you provide.
EDIT
From the responses I've learned that it happens because Double conforms to ExpressibleByIntegerLiteral protocol. However Float struct also does conform to it and some other types as well. Below I have created my struct that also conforms to that protocol. In the end however Double is chosen at compile time. Why? How is the precedence of method from one extension determined over the method from other extension ?
struct someStruct: ExpressibleByIntegerLiteral{
var i:Int = 0
init(integerLiteral value: Int64){
i = Int(value)
}
}
extension someStruct {
func someFunc() {print("Somestruct someFunc") }
}
extension Double {
func someFunc() { print("Double someFunc") }
}
4.someFunc()
//prints: Double someFunc
Type casting is a way to check the type of an instance, or to treat that instance as a different superclass or subclass from somewhere else in its own class hierarchy. Type casting in Swift is implemented with the is and as operators.
The Any type represents values of any type, including optional types. Swift gives you a warning if you use an optional value where a value of type Any is expected. If you really do need to use an optional value as an Any value, you can use the as operator to explicitly cast the optional to Any, as shown below. let optionalNumber: Int? = 3
It is used to check whether the instance type belongs to a particular super class or subclass or it is defined in its own hierarchy. Swift 4 type casting provides two operators 'is' to check the type of a value and 'as' and to cast the type value to a different type.
Type Casting for Any and AnyObject¶. Swift provides two special types for working with nonspecific types: Any can represent an instance of any type at all, including function types. AnyObject can represent an instance of any class type.
Double is one of the types that conforms to the protocol ExpressibleByIntegerLiteral. Since 2 is an integer leteral, the compiler can check which of the types conforming to the protocol has a someFunc() and since only Double does, there is no abiguity in this context.
Double
conforms to ExpressibleByIntegerLiteral. In your example, the compiler sees that of the all the types that conform to ExpressibleByIntegerLiteral
, only Double
contains someFunc()
, so it knows to create a Double
out of 2
.
As you noticed in your second example, this behaviour doesn't define implicit casting between types. It only applies to literals.
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