我刚刚注意到,Swift在Int和Double上做了一些类型转换。当我尝试评估
(10 / 3.0) - (10 / 3)
0.333...是预期的,但实际上是0.0。有人可以解释一下吗?
0.333...
0.0
是的,我也发现这很令人惊讶。Double同时符合FloatLiteralConvertibleand IntegerLiteralConvertible(ExpressibleByFloatLiteral和ExpressibleByIntegerLiteralSwift 3)。因此,Double可以使用 浮点文字 初始化a __
Double
FloatLiteralConvertible
IntegerLiteralConvertible
ExpressibleByFloatLiteral
ExpressibleByIntegerLiteral
let a = 3.0
或使用 整数文字 :
let b : Double = 10
(对于其他浮点类型(例如Float和 CGFloat)也是如此。)
Float
CGFloat
现在,对于我们所有人而言,(客观)C背景这两个语句可能都出乎了意料之外
let x : Double = 10/4 // x = 2.5 . Really? Yes! let y = 10/4 as Double // Same here ...
将值分配给0.25变量。从上下文来看,除法的结果必须为a,Double并且Swift不会隐式转换类型。因此/ 必须 是浮点除法运算符
0.25
/
func /(lhs: Double, rhs: Double) -> Double
因此,编译器会Double根据文字“ 10”和“ 4”将两个参数都创建为s。(如果将10/4其视为两个整数的除法,则结果也将是一个整数,并且无法将其分配给Double。)
10/4
请注意,这与
let z = Double(10/4) // z = 2.0 . (I just thought that I understood it &%$!?)
进行整数除法并将结果转换为Double。 Double有一个init(_ v: Int)构造函数,并且因此10/4 可以 被视为此处两个整数的分频。
init(_ v: Int)
如果我们总结一下这些结果,确实看起来有点奇怪:
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)只能是a Double,因此- 必须是浮点减法运算符
(10 / 3.0)
-
func -(lhs: Double, rhs: Double) -> Double
因此(10 / 3)也必须是一个Double。同样,/必须是浮点除法运算符,因此10和3被视为Double常量。
(10 / 3)
10
3
因此表达式等于
(Double(10) / 3.0) - (Double(10) / Double(3))
并计算为0.0。如果将表达式更改为
(10 / 3.0) - Double(10 / 3)
那么结果是0.333...因为在这种情况下10 / 3 是两个整数常数的除法,如上所述。
10 / 3