升级到 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
。第二次转换成功,并且使用 init:truncating
构造函数实例化 Float 也成功,即 z == 1.12
。将 n 强制转换为 Double 成功,但对我来说,这根本没有意义。
谁能给我解释一下这种行为吗? IE。谁能给我一个充分的理由为什么将 n 转换为 Float 失败?这是一个错误吗?如果这是预期行为,您能否引用 Swift 文档中描述此行为的位置?
最佳答案
这是 SE-0170 NSNumber bridging and Numeric types 的结果,在 Swift 4 中实现:
as?
forNSNumber
should mean "Can I safely express the value stored in this opaque box called a NSNumber as the value I want?".
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 转换为? float
成功。两者皆有
n.floatValue
Float(truncating: n)
可用于将数字“截断”为最接近的可表示形式 32 位浮点值。
关于ios - 将 NSNumber 转换为 Float 时出现意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57208635/