Why can't Swift find a Float extension method when calling an integer literal?

I have defined a method on Float called printme , and when I try to call it using an integer literal, Swift does not find the method:

 extension Float { func printme() { print("value: \(self)") } } 12.printme() // error: value of type 'Int' has no member 'printme' 

If I use an explicit action, it works:

 (12 as Float).printme() // prints "value: 12.0" 

Why, if Float conforms to the IntegerLiteralConvertible protocol, 12.printme() cannot find the method on Float ? It works if the type is Double , but does not execute for Int32 , UInt and other types. Why does this work for Double , but not for Float ?

Please note that the following works:

 func printit(f: Float) { print("value: \(f)") } printit(10) // prints "value: 10.0" 

Thus, it fails when the method is called in an integer literal, but not when the integer literal is a parameter of the function.


In Xcode 6.4, it does not work differently:

 12.printme() // error: cannot invoke 'printme' with no arguments 
+2
swift
source share
2 answers

Unless you have an explicit type, Swift assumes either Int or Double . From the Swift book :

For example, if you assign the literal value 42 to a new constant without specifying what type it is, Swift indicates that you want the constant to be Int , because you initialized it with a number that looks like an integer ... Similarly, if you If you don’t specify a type for the floating point literal, Swift will tell you that you want to create a Double .

Float not in the list of display types for literals. If you change the extension to Double, it works (Xcode 7.1):

 extension Double { func printme() { print("I'm a Double") } } 12.printme() 12.0.printme() 
+3
source share

For these types of extensions, I am looking for protocols of all types that I want to influence compliance too, rather than relying on the compiler to play well and convert Double to Float and vice versa.

IntegerLiteralConvertible works for everyone, but then you do not have access to a numerical value. If you add a restriction on IntegerType or FloatingPointType , you will get access to toIntMax() and self.advancedBy(0)

 extension IntegerLiteralConvertible where Self : IntegerType { func printMe() { print(self.toIntMax()) } } extension IntegerLiteralConvertible where Self : FloatingPointType { func printMe() { print(self.advancedBy(0)) } } let float = Float(10.234234) float.printMe() let double = Double(234.234234) double.printMe() let int = Int(234234) int.printMe() let int16 = Int16(234) int16.printMe() 
+2
source share

All Articles