我刚刚注意到Swift对Int和Double进行了一些类型转换。当我尝试评估时
(10 / 3.0) - (10 / 3)
应为0.333...
,但实际上是0.0
。有人能解释一下吗?
是的,我也觉得这很令人惊讶。CCD_ 3同时符合FloatLiteralConvertible
和IntegerLiteralConvertible
(Swift 3中的ExpressibleByFloatLiteral
和ExpressibleByIntegerLiteral
)。因此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 ...
将值CCD_ 11分配给变量。从上下文来看division必须是Double
,并且Swift不会隐式转换类型。因此/
必须为浮点除法算子
func /(lhs: Double, rhs: Double) -> Double
因此编译器从文字中创建两个参数作为Double
"10"one_answers"4"。(如果10/4
被视为两个整数的除法那么结果也是一个整数,不能赋值到CCD_ 16。)
请注意,这与不同
let z = Double(10/4) // z = 2.0 . (I just thought that I understood it &%$!?)
其进行整数除法并将结果转换为CCD_ 17。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
因此CCD_ 24也必须是CCD_。同样,/
必须是浮点除法运算符,因此10
和3
被视为Double
常数。
因此,该表达式等效于
(Double(10) / 3.0) - (Double(10) / Double(3))
并评估为CCD_ 30。如果将表达式更改为
(10 / 3.0) - Double(10 / 3)
则结果是Double
1,因为在这种情况下,10 / 3
是两个整数常数的除法,如上所述。