2016-12-14 42 views
15

我正在尝试使用NumberFormatter与Swift 3 Decimal,但我很困惑Decimal是如何真正实现的。我遇到的问题是Decimal是一个结构体,所以每次我想使用格式化程序时,我都必须将它连接到NSDecimalNumber,这是我想避免的。Swift 3 Decimal,NSDecimal和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或写更多的扩展?

编辑

我猜我想知道更多关于一般NSDecimalDecimalNSDecimalNumber在斯威夫特3.目前尚不清楚,我在所有东西是怎么回事。我应该用Decimal替换Swift 3替换NSDecimalNumber吗?该文档编写:

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

起初我以为这意味着Decimal是新NSDecimalNumberError是新NSError - 但现在我不那么肯定。这也表示“十进制值类型提供了与NSDecimalNumber引用类型相同的功能” - 这是真的吗?我似乎无法获得很多相同的功能(当然,没有先桥接它,那是什么意思?)。我在这里和那里发现了一些帖子和一些信息,但没有任何说服力。有没有人有任何知识或见解?

我的应用专门使用NSDecimalNumber进行货币和格式化,所以四舍五入和格式化是高优先级。

+2

据我所见,'NumberFormatter(style:.decimal)'不会编译,而且'NumberFormatter()'不会创建一个可选项。 - 这是你真正的代码,还是我忽略了一些东西? –

+0

'延伸的NumberFormatter { 方便的init(样式:NumberFormatter.Style){ self.init() self.numberStyle =风格 } FUNC串(从十进制:十进制) - >字符串? { return string(from:decimal as NSNumber) } }' –

+0

是的,这是我的真实代码,它编译得很好。我在Xcode 8.1上,有没有改变8.2或什么? – Alex

回答

12

我问我的SWIFT用户板的问题,并得到了精彩的回答,看看这里: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)的要求。

最终结果是Decimal很像IntDouble-它是一种值类型,可以方便地用来做各种数学运算。 NSDecimalNumber,则相当于NSNumber

由于我的应用程序正在进行大量格式化,因此需要在Decimal和NSDecimalNumber之间进行大量的转换,或者需要添加扩展名才能使用,所以我不认为没有多少扩展就会很自然。 Swift是否计划改进Decimal以更好地与NumberFormatter或其他面向对象的数字API一起使用?希望我已经提供了足够的信息来回答我的问题。

其使用NSDecimalNumber应桥接Decimal的Objective-C的API,就像NSString桥接到String。虽然桥接可能不适用于类别方法,您可以通过在Decimal上写入扩展名将这些扩展名发布到Swift,该扩展名将self转换为NSDecimalNumber,然后调用您的Objective-C方法。

同样,你应该能够通过强制转换为NSDecimalNumber使用DecimalNumberFormatter,就像你投IntDoubleNSNumberNumberFormatter使用它们。

+1

在'Double'类型上使用它的优点是什么? – brahimm

+0

@brahimm您绝对不应该使用Double/Float来表示货币。你可以在这里阅读一个很好的解释:https://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency – Caio

-3

使用此代码:

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

我有兴趣将Swift 3的Decimal类型转换为NumberFormatter而不是'NSNumber' – Alex

+0

为什么要使用Decimal '? –

+0

看到我上面的编辑...显然它可能会取代Swift中的NSDecimalNumber ...但它不清楚它是替换它还是只是添加一堆功能来表现它的样子或什么 – Alex