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 DecimalNSDecimalNumber 。我不清楚这里发生了什么事情。 我应该用Swift 3的DecimalreplaceNSDecimalNumber吗? 该文档写道:

Swift覆盖到Foundation框架提供了Decimal结构,它桥接到NSDecimalNumber类。 十进制值types提供了与NSDecimalNumber引用types相同的function,两者可以在与Objective-C API交互的Swift代码中互换使用。 这种行为类似于Swift将标准string,数字和集合types桥接到其相应的Foundation类。

起初,我认为这意味着Decimal是新的NSDecimalNumberError是新的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很像IntDouble 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来使用NumberFormatterDecimal ,就像你将IntDouble强制转换为NSNumber来使用NumberFormatter

使用此代码:

 let formatter = NumberFormatter() formatter.numberStyle = .decimal let string = formatter.string(from: NSNumber(integerLiteral: 3))