【问题标题】:How to make a struct conforms to a protocol which has a property conforms to another protocol in swift 4?如何使结构符合具有属性的协议符合swift 4中的另一个协议?
【发布时间】:2018-09-12 02:30:46
【问题描述】:

我打算将一些来自 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 {

    }
}

错误提示类型“XFNovelGetNovelsApiResponse”不符合协议“XFNovelApiResponse”。我知道“数据”属性应该以错误的方式实现。我该如何解决?谢谢。

【问题讨论】:

    标签: swift protocols decodable


    【解决方案1】:

    您要求描述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: ""))
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 2014-09-19
      相关资源
      最近更新 更多