我刚刚注意到Swift对Int和Double进行了一些类型转换。 当我尝试评估时
(10 / 3.0) - (10 / 3)
预计 0.333...
,但实际上是0.0
。
有人可以解释一下吗?
答案 0 :(得分:16)
是的,我也觉得这很令人惊讶。 Double
符合Swift 3中的FloatLiteralConvertible
和IntegerLiteralConvertible
(ExpressibleByFloatLiteral
和ExpressibleByIntegerLiteral
。因此a
可以使用浮点字面值
Double
let a = 3.0
或使用整数文字:
let b : Double = 10
(对于Float
和其他浮点类型也是如此
CGFloat
。)
现在,我们所有人都有(目标 - )C背景可能会出乎意料 这两个陈述
let x : Double = 10/4 // x = 2.5 . Really? Yes!
let y = 10/4 as Double // Same here ...
将值0.25
赋给变量。从上下文来看,结果是
除法必须是Double
,Swift不会隐式转换类型。
因此/
必须是浮点除法运算符
func /(lhs: Double, rhs: Double) -> Double
所以编译器从文字中创建两个参数Double
“10”和“4”。 (如果将10/4
视为两个整数的除法
那么结果也将是一个整数,并且无法分配
到Double
。)
请注意,这与
不同let z = Double(10/4) // z = 2.0 . (I just thought that I understood it &%$!?)
执行整数除法并将结果转换为Double
。
Double
有一个init(_ v: Int)
构造函数,因此10/4
可以在这里被视为两个整数的划分。
如果我们总结这些结果,这看起来有点奇怪:
let x : Double = 10/4 // x = 2.5
let y = 10/4 as Double // y = 2.5
let z = Double(10/4) // z = 2.0
现在我们可以将这些结果应用于您的表达式
(10 / 3.0) - (10 / 3)
第一部分(10 / 3.0)
只能是Double
,因此-
必须是浮点减法运算符
func -(lhs: Double, rhs: Double) -> Double
因此(10 / 3)
也必须是Double
。同样,/
必须是浮点除法运算符,因此10
和3
被视为Double
常量。
因此表达式等同于
(Double(10) / 3.0) - (Double(10) / Double(3))
并评估为0.0
。如果将表达式更改为
(10 / 3.0) - Double(10 / 3)
然后结果为0.333...
,因为在此上下文中10 / 3
是两个整数常量的除法,如上所述。