Swift中的隐式类型转换

时间:2016-12-07 08:24:29

标签: swift types casting swift3 implicit

播放来自Swift Language Guide: Extensions的示例代码我已经将这样的结构翻译为

extension Double {
    func someFunc() {
        print("someFunc")
    }
}

我很惊讶这句话

2.someFunc()

没有生成编译时错误,如:类型' Int'没有会员&some; cunc'。我预期值2将被隐式地转换为Int,但Swift将其转换为Double。这是为什么 ? Swift如何确定在这种情况下2的值是Double类型?

然后我尝试像那样调用someFunc()

let x = 2
x.someFunc()

这里我得到了预期的编译时错误

这是否与Swift Programming Language 3.0.1 : Language guide : The basics : Type Safety and Type Inference中的陈述相矛盾?

  

类型推断使编译器能够推断出特定类型   在编译代码时自动表达,简单地说   检查您提供的值。

修改

从回答中我了解到它发生是因为Double符合ExpressibleByIntegerLiteral协议。但是Float结构也确实符合它和其他一些类型。下面我创建了符合该协议的结构。最后,在编译时选择Double。为什么?一个扩展的方法的优先级如何通过其他扩展的方法确定?

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

2 个答案:

答案 0 :(得分:3)

Double是符合协议ExpressibleByIntegerLiteral的类型之一。由于2是整数leteral,编译器可以检查哪个符合协议的类型具有someFunc(),并且由于只有Double,所以在此上下文中没有任何歧义。

答案 1 :(得分:2)

Double符合ExpressibleByIntegerLiteral。在您的示例中,编译器会看到符合ExpressibleByIntegerLiteral的所有类型,只有Double包含someFunc(),因此它知道从{{Double创建2 1}}。

正如您在第二个示例中所注意到的,此行为并未定义类型之间的隐式转换。它仅适用于文字。