Swift 3 Decimal,NSDecimal和NSDecimalNumber

时间:2016-12-14 17:37:00

标签: ios swift swift3

我正在尝试将NumberFormatter与Swift 3 Decimal一起使用,但我对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)
    }
}

更一般地说,每次我需要传入一个对象类型时,我需要桥接Decimal或写更多扩展名吗?

修改

我想我更想知道Swift 3中NSDecimal DecimalNSDecimalNumber的情况。我根本不清楚这里发生了什么。对于Swift 3,我应该用NSDecimalNumber替换Decimal吗?文档写道:

  

Swift覆盖到Foundation框架提供了Decimal结构,该结构桥接到NSDecimalNumber类。 Decimal值类型提供与NSDecimalNumber引用类型相同的功能,并且这两者可以在与Objective-C API交互的Swift代码中互换使用。此行为类似于Swift如何将标准字符串,数字和集合类型桥接到相应的Foundation类。

首先我认为DecimalNSDecimalNumberErrorNSError是新NSDecimalNumber - 但现在我不太确定。这也说'十进制值类型提供与NSDecimalNumber引用类型相同的功能` - 这是真的吗?我似乎无法获得相同的功能(首先没有桥接,当然,这是他们的意思吗?)。我在这里和那里找到了一些帖子和一些信息,但没有任何令人信服的信息。有没有人有任何知识或见解?

我的应用专门使用navbar-fixed-top进行货币和格式设置,因此舍入和格式化是一个高优先级。

2 个答案:

答案 0 :(得分:26)

我在快速用户板上问了我的问题并得到了一个很好的答案,请在这里查看:https://lists.swift.org/pipermail/swift-users/Week-of-Mon-20161219/004220.html

回复的文字版本:

Swift 3引入了Decimal类,起初我认为它应该被替换为' Swift中的NSDecimalNumber,如Error是新的NSError等。但是,经过进一步调查,我不清楚实际情况如此。似乎Swift 3的Decimal不仅仅是一个NSDecimal,但是有一些桥接,所以它可以在需要时使用NSDecimalNumber的方法。我想知道的是,我应该用Decimal替换我的应用程序中的NSDecimalNumber吗? Decimal是Swift中NSDecimalNumber的继承者吗?

Decimal实际上是一个结构,而不是一个类,实际上它只是Objective-C中NSDecimal结构的Swift名称。在Swift中,NSDecimalAdd等函数在Decimal上作为运算符公开,用于满足SignedNumber等各种数字协议的要求。

最终结果是DecimalIntDouble非常相似 - 它是一种值类型,可以方便地用于进行各种数学运算。然后,NSDecimalNumber相当于NSNumber

由于我的应用程序正在进行大量格式化,因此需要在Decimal和NSDecimalNumber之间进行大量渲染,或者添加要使用的扩展,因此我认为没有很多扩展会很自然/方便。 Swift是否计划使用NumberFormatter或其他面向对象的数字API来提高Decimal的可用性?希望我已经提供了足够的信息来回答我的问题。

使用NSDecimalNumber的Objective-C API应桥接到Decimal,就像NSString桥接到String一样。但是,这种桥接可能不适用于类别方法;你可以通过在Decimal上编写一个扩展名来向Swift公开这些扩展,然后将self转换为NSDecimalNumber,然后调用Objective-C方法。

同样,您应该能够DecimalNumberFormatter一起使用NSDecimalNumber转换为Int,就像您将DoubleNSNumber投射到{{}一样1}}将它们与NumberFormatter一起使用。

答案 1 :(得分:-3)

使用此代码:

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