【问题标题】:Cannot convert value of type 'Codable' (aka 'Decodable & Encodable') to expected argument type 'T.Type'无法将“Codable”类型(又名“Decodable & Encodable”)的值转换为预期的参数类型“T.Type”
【发布时间】:2021-02-26 15:42:30
【问题描述】:

我正在研究一个处理 JSON 解析的小型结构。到目前为止,一切正常,除了我想将自定义结构作为结构传递给JSONDecoder().decode(type.self, from: data) 中的解码时使用,但这会引发以下错误:

无法将类型“Codable”(又名“Decodable & Encodable”)的值转换为预期的参数类型“T.Type”

private func parseJson(data: Data, type: Codable) -> Codable? {
    do {
        let decoded = try JSONDecoder().decode(type.self, from: data)
        
        return decoded
    } catch {
        print("JSON decode error: \(error.localizedDescription)")
    }
    
    return nil
}

有没有一种方法可以将结构传递给此方法以用作decode() 函数的类型?如果我直接在 decode() 函数上设置我试图传递给函数的类型,代码会按预期工作,它只会在我尝试传递它时出错。

【问题讨论】:

    标签: json swift xcode generics swift5


    【解决方案1】:

    你需要的是一个泛型方法:

    private func parseJson<T: Decodable>(data: Data, type: T.Type) -> T? {
        do {
            return try JSONDecoder().decode(type.self, from: data)
        } catch {
            print("JSON decode error:", error)
            return nil
        }
    }
    

    您也可以省略类型并显式设置结果对象的类型:

    private func parseJson<T: Decodable>(data: Data) -> T? {
        do {
            return try JSONDecoder().decode(T.self, from: data)
        } catch {
            print("JSON decode error:", error)
            return nil
        }
    }
    

    游乐场测试:

    struct User: Codable {
        let id: Int
        let name: String
    }
    let user: User = .init(id: 2, name: "abc")
    let userData = try! JSONEncoder().encode(user)
    
    let decodedUser: User = parseJson(data: userData)!
    decodedUser.name  // "abc"
    

    注意:我返回的是可选类型,但你绝对应该让你的方法抛出并返回一个非可选类型,如下所示,我正在扩展数据:

    extension Data {
        func decodedObject<T: Decodable>() throws -> T {
            try JSONDecoder().decode(T.self, from: self)
        }
    }
    

    do {
        let decodedUser: User = try userData.decodedObject()
        print(decodedUser.name)  // "abc"
    } catch {
        print(error)
    }
    

    【讨论】:

    • 这似乎有效,但我不太明白怎么做,你能再解释一下吗?
    • Codable 它不是一种类型,它是一种协议。 T 是泛型类型,需要符合Decodable
    猜你喜欢
    • 2018-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-18
    • 2023-03-24
    相关资源
    最近更新 更多