协议类型“可编码”的值不能符合“可编码”;只有struct / enum / class类型可以符合协议

时间:2020-06-07 22:34:17

标签: ios swift generics

我有以下Swift代码

func doStuff<T: Encodable>(payload: [String: T]) {
    let jsonData = try! JSONEncoder().encode(payload)
    // Write to file
}

var things: [String: Encodable] = [
    "Hello": "World!",
    "answer": 42,
]

doStuff(payload: things)

导致错误

Value of protocol type 'Encodable' cannot conform to 'Encodable'; only struct/enum/class types can conform to protocols

如何解决?我想我需要更改things的类型,但是我不知道该怎么做。

其他信息:

如果我将doStuff更改为非通用类型,那么我只会在该函数中遇到相同的问题

func doStuff(payload: [String: Encodable]) {
    let jsonData = try! JSONEncoder().encode(payload) \\ Problem is now here
    // Write to file
}

3 个答案:

答案 0 :(得分:6)

Encodable不能用作带注释的类型。它只能用作一般约束。并且JSONEncoder只能编码具体类型。

函数

func doStuff<T: Encodable>(payload: [String: T]) {

是正确的,但是您不能使用[String: Encodable]来调用该函数,因为协议不能符合自身。这正是错误消息所说的。


主要问题是things的真实类型是[String:Any],并且Any无法编码。

您必须使用things序列化JSONSerialization或创建一个辅助结构。

答案 1 :(得分:1)

您正在尝试使T符合Encodable,如果T == Encodable则无法。协议不符合自身。

您可以尝试:

func doStuff<T: Hashable>(with items: [T: Encodable]) {
    ...
}

答案 2 :(得分:1)

您可以将where关键字与Value类型结合使用,如下所示:

func doStuff<Value>(payload: Value) where Value : Encodable {
    ...
}