升级到 Xcode 9.3 (9E145) 后,我的应用程序显示了一些意外的行为。问题似乎在于将 NSNumber 转换为 Float。我用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
。第二次转换成功,并实例化了 Floatinit:truncating
构造函数也成功,即z == 1.12
。将 n 强制转换为 Double 成功,这对我来说根本没有意义。
谁能向我解释这种行为? IE。谁能给我一个充分的理由为什么将 n 转换为 Float 失败?这是一个错误吗?如果这是预期行为,您能否参考 Swift 文档中描述此行为的位置?
这是一个后果SE-0170 NSNumber 桥接和数字类型 https://github.com/apple/swift-evolution/blob/master/proposals/0170-nsnumber_bridge.md,在 Swift 4 中实现:
as?
for NSNumber
应该意味着“我可以安全地将存储在这个名为 NSNumber 的不透明框中的值表示为我想要的值吗?”。
1.12
是一个浮点文字,并推断为Double
, so 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 位浮点值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)