【问题标题】:Implicit type casting in SwiftSwift 中的隐式类型转换
【发布时间】:2016-12-07 08:24:29
【问题描述】:

使用来自Swift Language Guide: Extensions 的示例代码,我已经像这样扩展了 struct Double

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

我很惊讶这个说法

2.someFunc()

没有产生编译时错误,例如:“Int”类型的值没有成员“someFunc”。我预计 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

【问题讨论】:

  • 这是编辑中的一个好问题。

标签: swift types casting swift3 implicit


【解决方案1】:

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

【讨论】:

  • Float 结构也符合此协议,但无法编译。 extension Float { func someFunc() { print("float someFunc") } } 4.someFunc() 这就是所有需要的吗?如果我用 someFunc() 扩展了两个结构,我怎么知道在执行时会选择哪个?
  • 我认为这与此有关:“Swift 在推断浮点数的类型时总是选择 Double(而不是 Float)”developer.apple.com/library/content/documentation/Swift/…
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2013-07-09
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    • 2012-01-21
    • 1970-01-01
    • 2018-02-21
    相关资源
    最近更新 更多