Swift 3 Decimal,NSDecimal和NSDecimalNumber
我想用Swift 3 Decimal
来使用NumberFormatter
,但我很困惑如何实现Decimal
。 我遇到的问题是Decimal
是一个结构体,所以每次我想使用一个格式化程序时,我都必须将其连接到一个NSDecimalNumber
,这是我想避免的。
let formatter = NumberFormatter() formatter.numberStyle = .decimal let decimal = Decimal(integerLiteral: 3) let string = formatter.string(from: decimal as NSDecimalNumber)
是这个实现我自己的扩展需要Decimal
的理想解决方法?
extension NumberFormatter { open func string(from number: Decimal) -> String? { return string(from: number as NSDecimalNumber) } }
更一般地说,每次我需要传递一个对象types时,我将需要桥接Decimal
或写更多的扩展?
编辑
我想我一般NSDecimal
知道Swift 3中的NSDecimal
Decimal
和NSDecimalNumber
。我不清楚这里发生了什么事情。 我应该用Swift 3的Decimal
replaceNSDecimalNumber
吗? 该文档写道:
Swift覆盖到Foundation框架提供了Decimal结构,它桥接到NSDecimalNumber类。 十进制值types提供了与NSDecimalNumber引用types相同的function,两者可以在与Objective-C API交互的Swift代码中互换使用。 这种行为类似于Swift将标准string,数字和集合types桥接到其相应的Foundation类。
起初,我认为这意味着Decimal
是新的NSDecimalNumber
像Error
是新的NSError
– 但现在我不太确定。 这也表示“十进制值types提供了与NSDecimalNumber引用types相同的function” – 这是真的吗? 我似乎无法得到很多相同的function(当然,没有先搭桥,那是什么意思?)。 我在这里和那里发现了一些post和一些信息,但没有任何说服力。 有没有人有任何知识或见解?
我的应用程序专门使用NSDecimalNumber
进行货币和格式化,所以舍入和格式化是高优先级。
我在swift-users板上问了我的问题,并得到了一个很好的答案,在这里查看: https : //lists.swift.org/pipermail/swift-users/Week-of-Mon-20161219/004220.html
文本版本的回应:
Swift 3引入了Decimal类,起初我认为它应该在Swift中“replace”NSDecimalNumber,就像Error是新的NSError等一样。但是经过进一步的调查,我不清楚这是否是这种情况。 看来Swift 3的Decimal更像是一个NSDecimal,但是有一些桥接,所以它可以在需要的时候使用NSDecimalNumber的方法。 我想知道的是,我应该用Decimalreplace我的应用中的NSDecimalNumber吗? Decimal是Swift中NSDecimalNumber的inheritance者吗?
Decimal
实际上是一个结构体,而不是一个类,实际上它只是Objective-C中NSDecimal
结构体的Swift名称。 在Swift中,像NSDecimalAdd
这样的函数在Decimal
上作为运算符公开,用来满足像SignedNumber
这样的各种数字协议的要求。
最终的结果是Decimal
很像Int
或Double
it是一个值types,可以方便地用来做各种math。 NSDecimalNumber
则相当于NSNumber
。
由于我的应用程序正在进行大量的格式化,因此需要在Decimal和NSDecimalNumber之间进行大量的转换,或者添加要使用的扩展,所以我不认为没有很多扩展就没有必要。 Swift是否计划改进Decimal,使其更适用于NumberFormatter或其他面向对象的数字API? 希望我已经提供了足够的信息来回答我的问题。
使用NSDecimalNumber
Objective-C API应该桥接到Decimal
,就像NSString
被桥接到String
。 虽然桥接可能不适用于类别方法, 你可以通过在Decimal
上写一个扩展来将这些扩展到Swift,这个扩展将self
转换为NSDecimalNumber
,然后调用你的Objective-C方法。
同样,你应该能够通过强制转换为NSDecimalNumber
来使用NumberFormatter
的Decimal
,就像你将Int
或Double
强制转换为NSNumber
来使用NumberFormatter
。
使用此代码:
let formatter = NumberFormatter() formatter.numberStyle = .decimal let string = formatter.string(from: NSNumber(integerLiteral: 3))