升级到Xcode 9.3(9E145)后,我的应用程序显示了一些意外行为。看来问题在于将NSNumber强制转换为Float。我as为此使用类型强制转换运算符。请参见以下示例。
as
let n = NSNumber.init(value: 1.12) let m = NSNumber.init(value: 1.00) let x = n as? Float let y = m as? Float let xd = n as? Double let z = Float(truncating: n)
在此,第一次强制转换失败,即x == nil。第二次强制转换成功,并且使用init:truncating构造函数实例化Float 也成功,即z == 1.12。从n到Double的转换成功,对我而言,这毫无意义。
x == nil
init:truncating
z == 1.12
谁能向我解释这种行为?即是谁能给我一个很好的理由,说明为什么将n强制转换为Float?这是一个错误吗?如果这是预期的行为,那么您可以参考Swift文档中描述此位置的位置吗?
这是在Swift 4中实现的SE-0170 NSNumber桥接和数字类型的结果:
as?for NSNumber应该表示“我可以安全地将存储在不透明框中的称为NSNumber的值表示为所需的值吗?”。
as?
NSNumber
1.12是一个浮点文字,并推断为a Double,因此NSNumber(value: 1.12)对最接近的64位浮点值进行“装箱” 1.12。将其转换为32位Float不会保留此值:
1.12
Double
NSNumber(value: 1.12)
Float
let n = NSNumber(value: 1.12) let x = Float(truncating: n) // Or: let x = n.floatValue let nn = NSNumber(value: x) print(n == nn) // false
另一方面,1.0可以完全表示为Float:
1.0
let m = NSNumber(value: 1.0) let y = m.floatValue let mm = NSNumber(value: y) print(m == mm) // true
这就是铸造m as? Float成功的原因。都
m as? Float
n.floatValue Float(truncating: n)
可用于将数字“截断”到最接近的可表示32位浮点值。