为什么 NumberFormatter 的字符串(from:) 返回一个可选?



>文档链接

为什么NumberFormatter函数func string(from number: NSNumber) -> String?返回String?而不是String?对于此函数可能返回 nil 的NumberFormatter,是否存在特定的输入或状态?有时我听说这些不太理想的返回类型来自 Objective-C 保留文件,这是其中一种情况吗?

只是为了好玩:这是一个(构造的,不是现实世界的)示例,其中string(from:)实际上返回nil

let num = NSNumber(bytes: UnsafeRawPointer(bitPattern: 1)!, objCType: "v")
print(num) // <>
let fmt = NumberFormatter()
fmt.numberStyle = .decimal
let str = fmt.string(from: num)
print(str as Any) // nil

原因是这个num不代表一个数字:它是创建的 使用NSValue(其继承自)初始值设定项init(bytes:objCType:)的值表示void。("v"是void的类型编码, 指针值无关紧要。

苹果邮件列表中有一个古老的(2002)回复,可能会部分回答你的问题:

奇怪的行为不是NSNumber - NSNumber -stringValue似乎返回了人们期望的结果。NSNumberFormatter返回了不寻常的结果。

这里的抽象问题是,NSNumberFormatter最初是为处理EOF的资金金额而编写的,因此它不能很好地处理异常数字(或通用字符串格式)。

更具体的问题是,当你向NSNumberFormatter询问-stringForObjectValue:时,如果对象不是NSDecimalNumber,它会使用以下命令将其转换为NSDecimalNumber。 [NSDecimalNumber decimalNumberWithString:[objectValue stringValue]] 除了潜在的其他问题外,这不会很好地处理异常值。另一个问题,虽然我不知道是这种情况,但我认为没有像 NaN 那样存在正无穷大和负无穷大的 NSDecimal(结构)表示。

我实际上不太理解这种响应,无法说这就是返回可选的原因,但我怀疑它是相关的。

原始问题中有示例代码,但没有一个返回nil,它总是给出一个字符串。

我认为可以公平地说,如果您尝试使用NumberFormatter将通用类型(如Double)格式化为String,则它不可能返回nil

在我看来,这是强制解开可选选项完全合理的少数情况之一。

func formatToDecimalNumber(_ value: Double) -> String {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = 2
formatter.locale = Locale.current
return formatter.string(from: NSNumber(value: value))!
}

最新更新