当前位置: 首页 > 面试题库 >

使用值有时为Int且有时为String的可编码

游鸣
2023-03-14
问题内容

我有一个API,有时会id以Int的形式在JSON中返回特定的键值(在本例中为),而有时它会返回与String相同的键值。如何使用可编码解析该JSON?

struct GeneralProduct: Codable {
    var price: Double!
    var id: String?
    var name: String!

    private enum CodingKeys: String, CodingKey {
        case price = "p"
        case id = "i"
        case name = "n"
    }

    init(price: Double? = nil, id: String? = nil, name: String? = nil) {
        self.price = price
        self.id = id
        self.name = name
    }
}

我不断收到此错误消息:Expected to decode String but found a number instead。它返回数字的原因是因为id字段为空,并且当id字段为空时,默认情况下返回0作为ID,可编码的ID标识为数字。我基本上可以忽略ID密钥,但是codable并不能让我选择忽略它。处理此问题的最佳方法是什么?

这是JSON。超级简单

加工

{
  "p":2.12,
  "i":"3k3mkfnk3",
  "n":"Blue Shirt"
}

错误-由于系统中没有id,因此它默认返回0,可编码的代码显然将其视为与字符串相反的数字。

{
  "p":2.19,
  "i":0,
  "n":"Black Shirt"
}

问题答案:
struct GeneralProduct: Codable {
    var price: Double?
    var id: String?
    var name: String?
    private enum CodingKeys: String, CodingKey {
        case price = "p", id = "i", name = "n"
    }
    init(price: Double? = nil, id: String? = nil, name: String? = nil) {
        self.price = price
        self.id = id
        self.name = name
    }
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        price = try container.decode(Double.self, forKey: .price)
        name = try container.decode(String.self, forKey: .name)
        do {
            id = try String(container.decode(Int.self, forKey: .id))
        } catch DecodingError.typeMismatch {
            id = try container.decode(String.self, forKey: .id)
        }
    }
}
let json1 = """
{
"p":2.12,
"i":"3k3mkfnk3",
"n":"Blue Shirt"
}
"""

let json2 = """
{
"p":2.12,
"i":0,
"n":"Blue Shirt"
}
"""
do {
    let product = try JSONDecoder().decode(GeneralProduct.self, from: Data(json2.utf8))
    print(product.price ?? "nil")
    print(product.id ?? "nil")
    print(product.name ?? "nil")
} catch {
    print(error)
}

编辑/更新

您还nil可以id在api返回时简单地分配给您0

do {
    let value = try String(container.decode(Int.self, forKey: .id))
    id = value == "0" ? nil : value
} catch DecodingError.typeMismatch {
    id = try container.decode(String.self, forKey: .id)
}


 类似资料:
  • 问题内容: 我是第一次遇到,很惊讶,因为Java已经具有一个非常强大的类,可以追加。 为什么要上第二堂课? 在哪里可以了解更多信息? 问题答案: 不允许附加。你在上调用的每个方法都会创建一个新对象并返回它。这是因为String它是不可变的-无法更改其内部状态。 另一方面是可变的。调用时,它会更改内部char数组,而不是创建新的字符串对象。 因此,拥有: 而不是,这将创建500个新的字符串对象。 请

  • 我正在尝试读取包含以下字段和值的csv文件: 引用字段是唯一的,选择字段可能为空。在此场景中,对于我的实体定义: 1.我应该为字段使用吗,因为它在csv文件中可能为空(空字符串)? 2.我应该使字段PK还是即使它是唯一的,我认为最好使用id字段并为字段添加。对吗? 3、对于开始日期字段,我认为应该使用本地日期,而不是日期,因为它已被弃用。这是真的吗?

  • C#中问号的左右表示可空,那string能不能打问号?为什么我有时候可以打问号,有时候又不能,打了问号会报错? 问了我的组长和同事,他们说自己也不大清楚,网络上搜索也没有得到有效的辨析答案

  • 问题内容: 我正在Swift iOS应用程序中使用类型的参数列表来保存一些最终将传递给Web服务的参数。如果我将Bool保存到此字典中然后打印,它会显示为“ Optional(1)”,因此正在将其转换为int。我无法发送一个int,并且需要将其设为“ true”。下面的示例代码。 我怎样才能将其保存为实际的true / false值而不是整数? 注意事项 这与AFNetworking一起使用,因此

  • 问题内容: 上限为-2147483648至2147483647。 如果我输入 然后Eclipse将在“ 2147483648”下提示红色下划线。 但是,如果我这样做: 它将编译良好。 也许这是Java中的一个基本问题,但是我不知道为什么第二个变体不会产生任何错误。 问题答案: 那句话没有错。您只是将4个数字相乘并将其分配给一个int,恰好发生溢出。这与分配单个 文字 不同,后者在编译时会进行边界检

  • 我的数据库中有一些值,如果还没有输入的话,它们可能为空。 但是当我在我的html中使用Thymeleaf时,它在解析空值时出错。 这个有什么办法处理吗