Eug*_*nok 12 casting type-inference swift
我刚刚注意到Swift对Int和Double进行了一些类型的转换.当我尝试评估时
(10 / 3.0) - (10 / 3)
Run Code Online (Sandbox Code Playgroud)
0.333...预计,但实际上0.0.有人可以解释一下吗?
Mar*_*n R 17
是的,我也发现这非常令人惊讶.Double符合两者FloatLiteralConvertible和IntegerLiteralConvertible(ExpressibleByFloatLiteral和ExpressibleByIntegerLiteralSwift 3).因此,Double可以使用浮点字面值初始化a
let a = 3.0
Run Code Online (Sandbox Code Playgroud)
或者使用整数文字:
let b : Double = 10
Run Code Online (Sandbox Code Playgroud)
(对于像Float和
等的其他浮点类型也是如此CGFloat.)
现在,对于我们所有具有(Objective-)C背景的人来说,这两种说法都可能出乎意料
let x : Double = 10/4 // x = 2.5 . Really? Yes!
let y = 10/4 as Double // Same here ...
Run Code Online (Sandbox Code Playgroud)
将值0.25赋给变量.从上下文来看,除法的结果必须是a Double并且Swift不会隐式转换类型.因此/ 必须是浮点除法运算符
func /(lhs: Double, rhs: Double) -> Double
Run Code Online (Sandbox Code Playgroud)
所以编译器Double从文字"10"和"4" 创建两个参数.(如果10/4被视为两个整数的除法,那么结果也将是一个整数,并且不能分配给Double.)
请注意,这与...不同
let z = Double(10/4) // z = 2.0 . (I just thought that I understood it &%$!?)
Run Code Online (Sandbox Code Playgroud)
它执行整数除法并将结果转换为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
Run Code Online (Sandbox Code Playgroud)
现在我们可以将这些结果应用于您的表达式
(10 / 3.0) - (10 / 3)
Run Code Online (Sandbox Code Playgroud)
第一部分(10 / 3.0)只能是a Double,因此-
必须是浮点减法运算符
func -(lhs: Double, rhs: Double) -> Double
Run Code Online (Sandbox Code Playgroud)
因此(10 / 3)也必须是一个Double.再次,/必须是浮点除法运算符,因此10和3被视为Double常数.
因此表达式相当于
(Double(10) / 3.0) - (Double(10) / Double(3))
Run Code Online (Sandbox Code Playgroud)
并评估为0.0.如果将表达式更改为
(10 / 3.0) - Double(10 / 3)
Run Code Online (Sandbox Code Playgroud)
那么结果是0.333...因为在这种情况下,10 / 3
是两个整数常数的除法,如上所述.