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

时间:2018-01-29 15:24:07

标签: ios swift

Documentation link

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

3 个答案:

答案 0 :(得分:6)

Apple mailing list上有一个古老的(2002年)回复,可能会部分回答你的问题:

  

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

     

这里的抽象问题是NSNumberFormatter最初用于处理EOF的金额,因此它不能很好地处理不寻常的数字(或者通用字符串格式化)。

     

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

我实际上并不理解这种反应足以说明为什么会返回可选项,但我怀疑它是否相关。

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

答案 1 :(得分:6)

只是为了好玩:这是一个(构建的,不是真实世界)的例子 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的{​​{3}}, 指针值无关紧要。)

答案 2 :(得分:0)

我认为这很容易,如果您尝试使用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))!
}