如何使结构符合具有 属性 的协议符合 swift 4 中的另一个协议?

How to make a struct conforms to a protocol which has a property conforms to another protocol in swift 4?

我打算将 Web 服务中的一些 JSON 数据反映到 swift 结构中。所以我创建了一个符合可解码协议的协议,并计划创建一些结构来符合它。这是我创建的协议:

protocol XFNovelApiResponse: Decodable {

   var data: Decodable {get}
   var error: NovelApiError {get}
}

struct NovelApiError: Decodable {

   let msg: String
   let errorCode: String
}

已编译。但是当我开始编写我的结构时,我遇到了一个错误。该结构的代码在这里:

struct XFNovelGetNovelsApiResponse: XFNovelApiResponse {

    let data: NovelsData

    let error: NovelApiError

    struct NovelsData: Decodable {

    }
}

错误说 type 'XFNovelGetNovelsApiResponse' 不符合协议 'XFNovelApiResponse'。我知道 'data' 属性 应该以错误的方式实施。我该如何解决?谢谢

您要求描述 data 可以容纳的类型,而不是实际类型。这意味着它需要是 associatedtype:

protocol XFNovelApiResponse: Decodable {
    associatedtype DataType: Decodable
    var data: DataType {get}
    var error: NovelApiError {get}
}

请注意,具有关联类型的协议会产生很多复杂性,因此您应该仔细考虑该协议是否真的有必要,或者 XFNovelApiResponse 是否可以,例如,改为通用的。这取决于其他什么类型实现了这个协议。

例如,没有协议的一组类似数据结构的另一种实现是:

struct XFNovelApiResponse<DataType: Decodable>: Decodable {
    var data: DataType
    var error: NovelApiError
}

struct NovelsData: Decodable {
}

struct NovelApiError: Decodable {

    let msg: String
    let errorCode: String
}

let novels = XFNovelApiResponse(data: NovelsData(),
                                error: NovelApiError(msg: "", errorCode: ""))

或者,您可以使用允许继承的 类 和 sub类 来实现。结构不继承自协议,它们符合协议。如果你真的想继承,类 是正确的工具。 (但我希望泛型在这里是更好的解决方案。)