2016-12-14 68 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