为什么Swift在调用整数文字时不能找到Float扩展方法?

时间:2015-12-03 14:28:29

标签: swift

我在Float上定义了一个名为printme的方法,当我尝试使用整数文字调用它时,Swift无法找到该方法:

extension Float {
    func printme() {
        print("value: \(self)")
    }
}

12.printme()    // error: value of type 'Int' has no member 'printme'

如果我使用显式转换,它可以工作:

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

为什么,如果Float符合 IntegerLiteralConvertible 协议,12.printme()无法在Float上找到方法?如果类型有效 是Double,但Int32UInt和其他类型都失败了。 为什么它适用于Double,但不适用于Float

请注意以下内容确实有效:

func printit(f: Float) {
    print("value: \(f)")
}

printit(10)              // prints "value: 10.0"

因此,当在整数文字上调用方法时失败,但在整数文字是函数的参数时则失败。

Xcode 6.4 中,它以不同的方式失败:

12.printme()  // error: cannot invoke 'printme' with no arguments

2 个答案:

答案 0 :(得分:3)

如果您没有明确的类型,Swift会假定IntDouble。来自Swift book

  

例如,如果您将一个文字值42分配给一个新常量而不说它是什么类型,Swift会推断您希望该常量为Int,因为您已使用一个数字初始化它看起来像一个整数...同样,如果你没有为浮点文字指定一个类型,Swift推断你要创建一个Double

Float不在文字的推断类型列表中。如果您将扩展名更改为Double,则可以正常工作(Xcode 7.1):

extension Double {
    func printme() {
        print("I'm a Double")
    }
}

12.printme()
12.0.printme()

答案 1 :(得分:2)

对于这些类型的扩展,我寻找协议所有类型我想要影响的协议,而不是指望它编译器会很好地将Double转换为Float,反之亦然

IntegerLiteralConvertible适用于所有人,但是您无法访问数值。如果您向IntegerTypeFloatingPointType添加约束,则可以访问toIntMax()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()