根據我的問題,我想將 json 的每個欄位解碼為字串值。
我的 json 看起來像這樣
{ name: "admin_tester",
price: 99.89977202,
no: 981,
id: "nfs-998281998",
amount: 98181819911019.828289291329 }
我想像這樣創建我的結構
struct StockNFS: Decodable {
let name: String?
let price: String?
let no: String?
let id: String?
let amount: String?
}
但是如果我這樣宣告我的結構,當我使用 json 解碼時,我會得到錯誤不匹配型別
我想將每個值映射到字串的原因,是因為如果我對price
and使用雙精度或十進制amount
,在編碼之后有時值會不正確。例如 0.125,我將得到 0.124999999。
我只想接收字串型別的任何資料,以便在 ui 上顯示(而不是編輯或操作值)
我將不勝感激任何幫助。非常感謝。
uj5u.com熱心網友回復:
為了避免浮點問題,我們可以使用 String 或 Decimal 型別作為鍵價格和金額。在任何一種情況下,我們都不能直接解碼為任何一種型別,但我們首先需要使用給定的型別 Double,因此我們需要一個自定義的 init。
第一種情況是使用字串(我認為沒有理由使用可選欄位作為默認值,如果任何欄位實際上可以為零,請更改此設定)
struct StockNFS: Codable {
let name: String
let price: String
let no: Int
let id: String
let amount: String
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
let priceValue = try container.decode(Double.self, forKey: .price)
price = "\(priceValue.roundToDecimal(8))"
//... rest of the values
}
}
四舍五入與靈感來自這個優秀答案的方法一起使用
extension Double {
func roundToDecimal(_ fractionDigits: Int) -> Double {
let multiplier = pow(10, Double(fractionDigits))
return (self * multiplier).rounded() / multiplier
}
}
做同樣的事情,但Decimal
我們做的數字型別
struct StockNFS2: Codable {
let name: String
let price: Decimal
let no: Int
let id: String
let amount: Decimal
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
let priceValue = try container.decode(Double.self, forKey: .price)
price = Decimal(priceValue).round(.plain, precision: 8)
//... rest of the values
}
}
再次舍入方法的靈感來自相同的答案
extension Decimal {
func round(_ mode: Decimal.RoundingMode, precision: Int = 2) -> Decimal {
var result = Decimal()
var value = self
NSDecimalRound(&result, &value, precision, mode)
return result
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/360597.html