升级到Xcode 9.3(9E145(后,我的应用程序出现了一些意外的行为。似乎问题出在将 NSNumber 转换为浮点数上。为此,我使用 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到双倍的演员阵容成功了,对我来说,这根本没有意义。
谁能向我解释这种行为? 即,谁能给我一个很好的理由,为什么 n 到 Float 的转换失败?这是一个错误吗?如果这是预期的行为,您能否参考 Swift 文档中描述此内容的位置?
这是 SE-0170 NSNumber 桥接和数值类型的结果,在 Swift 4 中实现:
NSNumber
as?
应该意味着"我是否可以安全地将存储在这个称为 NSNumber 的不透明框中的值表示为我想要的值?
1.12
是一个浮点字面,并推断为Double
,所以NSNumber(value: 1.12)
是"装箱"64位浮点值最接近1.12
.将其转换为 32 位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
:
let m = NSNumber(value: 1.0)
let y = m.floatValue
let mm = NSNumber(value: y)
print(m == mm) // true
这就是铸造m as? Float
成功的原因。双
n.floatValue
Float(truncating: n)
可用于将数字"截断"为最接近的可表示值32 位浮点值。