Is it possible to extend NSDecimalNumber
to conform Encodable & Decodable
protocols?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
It is not possible to extend NSDecimalNumber
to conform to Encodable
& Decodable
protocols. Jordan Rose explains it in the following swift evolution email thread.
If you need NSDecimalValue
type in your API you can build computed property around Decimal
.
struct YourType: Codable {
var decimalNumber: NSDecimalNumber {
get { return NSDecimalNumber(decimal: decimalValue) }
set { decimalValue = newValue.decimalValue }
}
private var decimalValue: Decimal
}
Btw. If you are using NSNumberFormatter
for parsing, beware of a known bug that causes precision loss in some cases.
let f = NumberFormatter()
f.generatesDecimalNumbers = true
f.locale = Locale(identifier: "en_US_POSIX")
let z = f.number(from: "8.3")!
// z.decimalValue._exponent is not -1
// z.decimalValue._mantissa is not (83, 0, 0, 0, 0, 0, 0, 0)
Parse strings this way instead:
NSDecimalNumber(string: "8.3", locale: Locale(identifier: "en_US_POSIX"))
回答2:
In swift you should use Decimal type. This type confirms to protocols Encodable & Decodable
from the box.
If you have NSDecimalNumber
type in your code it's easy to cast it to Decimal
let objcDecimal = NSDecimalNumber(decimal: 10)
let swiftDecimal = (objcDecimal as Decimal)