简体   繁体   English

Swift 扩展 - 必须在非专用泛型类型“数组”上声明约束扩展

[英]Swift extension - Constrained extension must be declared on the unspecialized generic type 'Array'

I have an API that returns a JSON array of objects.我有一个返回 JSON 对象数组的 API。 I've setup the structure to look as follows:我已将结构设置为如下所示:

typealias MyModels = [MyModel]

struct MyModel: Codable {
    let field1: String
    let field2: String
    let mySubModel: SubModel?
    
    enum CodingKeys: String, CodingKey {
        case field1 = "Field1"
        case field2 = "Field2"
        case mySubModel = "MySubModel"
    }
}

struct SubModel: Codable {
    let subModelField1: String
    let subModelField2: String
    
    enum CodingKeys: String, CodingKey {
        case subModelField1 = "SubModelField1"
        case subModelField2 = "SubModelField2"
    }
}

What I want to do is add this extension, supplying a path var (the NetworkModel protocol provides some base functionality for API operations):我想要做的是添加这个扩展,提供一个路径变量(NetworkModel 协议为 API 操作提供了一些基本功能):

extension MyModels: NetworkModel {
    static var path = "the/endpoint/path"
}

I don't have any issues in other model/struct classes that I setup in this way when the base is an object or json key.当基础是对象或 json 键时,我以这种方式设置的其他模型/结构类没有任何问题。 However, since this one is different and simply is an array, I get this error when I put that extension in the class:但是,由于这个不同并且只是一个数组,因此当我将该扩展名放入类中时会出现此错误:

Constrained extension must be declared on the unspecialized generic type 'Array' with constraints specified by a 'where' clause约束扩展必须在非特化泛型类型“数组”上声明,约束由“where”子句指定

I've done some digging and tried a few things with a where clause on the extension, but I'm just a bit confused as to what it wants.我已经做了一些挖掘并尝试了一些关于扩展的 where 子句的事情,但我对它想要什么感到有点困惑。 I'm sure it's something simple, but any thoughts on this?我敢肯定这很简单,但是对此有什么想法吗? If I need to go about it a different way with the typealias above, I'm fine with that.如果我需要使用上面的 typealias 以不同的方式处理它,我可以接受。 Thanks in advance!提前致谢!

The error is basically telling you to do this:该错误基本上是告诉您这样做:

extension Array : NetworkModel where Element == MyModel {
    static var path = "the/endpoint/path"
}

You can't simply make an extension of [MyModel] .您不能简单地扩展[MyModel]

Although Sweeper answered the question appropriately based on the initial question, I wanted to provide an alternative approach, even if potentially slightly more complex.尽管 Sweeper 根据最初的问题适当地回答了这个问题,但我想提供一种替代方法,即使可能稍微复杂一些。 This can be accomplished by overriding the Decodable side of things and manually putting the models into a list:这可以通过覆盖事物的可解码方面并手动将模型放入列表来完成:

struct MyModels: Codable {
    var modelList: [MyModel] = []

    public init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        let metaType = (Account.self as Decodable.Type)

        while !container.isAtEnd {
            let subdecoder = try container.superDecoder()
            if let model = try metaType.init(from: subdecoder) as? MyModel {
                modelList.append(model)
            }
        }
    }
}

struct MyModel: Codable {
    let subModelField1: String
    let subModelField2: String

    enum CodingKeys: String, CodingKey {
        case subModelField1 = "SubModelField1"
        case subModelField2 = "SubModelField2"
    }
}

extension MyModels: NetworkModel {
    static var path = "the/endpoint/path"
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM