带扩展名的自动类型转换:这里发生了什么?

时间:2014-06-02 22:07:40

标签: swift

我正在阅读The Swift Programming Language本书的第一章,我正处于描述extension关键字的部分。

我参加了“实验”:

  

“为添加absoluteValue属性的Double类型编写扩展名。”

我得到了这样的工作:

extension Double {
    var absoluteValue: Double {
        if(self < 0) {
            return self * -1
        }

        return self
    }
}

(-10.5).absoluteValue    // 10.5

但它似乎也适用于整数:

(-4).absoluteValue       // 4.0

这里发生了什么?编译器是否将类型从Int更改为Double,因为它看到absoluteValue上有Double个扩展名而不是Int

似乎是这种情况,因为如果我在extension上添加同名的Int,就像这样:

extension Int {
    var absoluteValue: Int {
        return 42
    }
}

这会覆盖extension上的Double。并(-4).absoluteValue返回42

有没有办法添加extension 仅适用于Double而不是Int s?

编辑:看起来它正在编译时进行转换,因为我没有为我的文字定义一个类型,所以它转换了它。以下产生错误

var i:Int = -4;
i.absoluteValue
  

“游乐场执行失败:错误:: 12:1:错误:'Int'没有名为'absoluteValue'的成员   i.absoluteValue   ^ ~~~~~~~~~~~~~“

编辑2:它似乎只适用于文字;以下内容也会产生错误:

var i = -4;
i.absoluteValue

2 个答案:

答案 0 :(得分:3)

是的,您撰写的扩展程序实际上仅适用于Double s,而不适用于Int s。看一下这个例子:

extension Double {
    var absoluteValue: Double {
        if (self < 0) {
            return self * -1
        }

        return self
    }
}

var double: Int = 10
double.absoluteValue // Int does not have a member named absoluteValue

但是,在您的代码中,编译器会隐式地将您的Int转换为Double

答案 1 :(得分:3)

如果有人想要符合示例协议的答案:

protocol ExampleProtocol {
    var simpleDescription: String { get }
    mutating func adjust()
}

extension Double: ExampleProtocol {
    var simpleDescription: String {
        return "The number \(self)"
    }
    var absoluteValue: Double {
        return fabs(self)
    }
    mutating func adjust() {
        self = round(self)
    }
}
var double: Double = -12.34
double.simpleDescription
double.absoluteValue