import Foundation

let json = """
{
    "property": null
}
""".data(using: .utf8)!

struct Program<T: Decodable>: Decodable {
    let property: T
    
    static func decode() {
        do {
            try JSONDecoder().decode(Self.self, from: json)
        } catch {
            print("Error decoding \(T.self): \(error)\n")
        }
    }
}

Program<String>.decode()
Program<Int>.decode()
Program<[Double]>.decode()
Program<[String: Int]>.decode()
Program<Bool>.decode()

For every case, except for Bool, we get valueNotFound("Cannot get unkeyed decoding container -- found null value instead") error. Which is correct, according to the documentation.
Only for Bool, for some reason, we get typeMismatch("Expected to decode Bool but found null instead.") error.

推荐答案

在Linux(fiddle)上,[Double]产生valueNotFound,其他所有的都产生typeMismatch.这与swift-core-libs-foundation的源代码一致,其中unkeyedContainer(在对数组进行解码时调用)抛出valueNotFound(source):

@usableFromInline func unkeyedContainer() throws -> UnkeyedDecodingContainer {
    switch self.json {
    case .array(let array):
        ...
    case .null:
        throw DecodingError.valueNotFound([String: JSONValue].self, DecodingError.Context(
            codingPath: self.codingPath, 
            debugDescription: "Cannot get unkeyed decoding container -- found null value instead"
        ))
    default:
        ...
    }
}

typeMismatch由为解码"标量"类型而创建的单个值容器抛出(source).

func decode(_: Bool.Type) throws -> Bool {
    guard case .bool(let bool) = self.value else {
        throw self.impl.createTypeMismatchError(type: Bool.self, value: self.value)
    }

    return bool
}

正因为如此,我怀疑macOS上的JSONDecoder并没有故意实现为Bool抛出typeMismatch和其他valueNotFound.它似乎使用JSONSerialization API将JSON解码为NSDictionary.Bool与其他类型的行为可能是怪癖的结果.

我个人认为文档中typeMismatchvalueNotFound的措辞足够宽松,当遇到null值时,抛出两者都是"正确的".

Json相关问答推荐

最新版本的Deneb在数据溢出时不支持滚动

从Json响应中为需要每个值的Post请求提取多个值

如何使用JQ将JSON字符串替换为解析后的类似功能?

如何使用JQ打印每个根级对象键一行?

在PowerShell中,如何获取数据对所在的JSON对象的名称

如何用JQ打印JSON文件的路径和键值

数据到jsonObject到数据到 struct 是可能的吗?

Powershell ConvertFrom-Json 意外地从包含字符串的单个项目数组生成字符串而不是对象数组

使用动态语言jQuery:根据匹配模式提取与其他值匹配的值

JOLT转换并向输出添加新数组

派生类的属性没有得到价值

使用 System.Text.Json 序列化记录成员

Laravel5 Json 获取文件内容

在 JSON 反序列化期间没有为System.String类型定义无参数构造函数

jquery用json数据填充下拉列表

Spring Security 和 JSON 身份验证

使用 Node.js 对 JSON 中的字符串大小有限制吗?

JSON Schema:验证数字或空值

在 HTML 数据属性上添加 JSON 是不是很糟糕?

Python 到 JSON 序列化在十进制上失败