简体   繁体   中英

Swift type does not conform to protocol error at generic constraint but not at class itself

I'm having some troubles figuring this whole thing out here. Starting from code:

Entity:

protocol EntityProtocol : class {
    var id: String { get set }
    var version: String { get }
    var deleted: Bool { get set }
    var uid: String { get set }
    func Validate() -> [String: String]
}
extension EntityProtocol {
    var version: String {
        get { return "v0.0" }
        set { }
    }
    func Validate() -> [String: String]{
        //some default checking for default fields
    }
}
typealias Entity = EntityProtocol & Codable

Product:

class Product: Entity {
    var id: String = ""
    var deleted: Bool
    var uid: String = ""

    func Validate() -> [String : String] {
      //implementation
    }
}

Up until now, no errors when compiling... Then I have class Repository<TEntity> where TEntity: Entity a base class which implements the actual repository functionality...

Now when I do class ProductRepo<Product>: Repository<Product> it shows an error here saying Type 'Product' does not conform to protocol 'EntityProtocol' However, still no error in the Product class itself.

PS: I've tried to add the version field to product, still same error. The reason I'm using protocol not class with inheritance is that Codable can not be inherited and will have to write init and serialize myself.

Anyone can tell me why this is happening and how to fix it? I'm confused that if Product does not conform to protocol, then why compiler does not complain in the Product class itself?

U tried adding version field to product, but u should also make version {get set} in EntityProtocol protocol then it will work

protocol EntityProtocol : class {
    var id: String { get set }
    var version: String { get }
    var deleted: Bool { get set }
    var uid: String { get set }
    func Validate() -> [String: String]
}

Your ProductRepo declaration is missing a type constraint on Product . You need to add the Entity constraint to it to make it conform to Repository .

class ProductRepo<Product: Entity> : Repository<Product> {
    
}

Unrelated to your question, but there's no need for having Entity as a type alias, you can simply make EntityProtocol conform to Codable . Also, for the version default implementation, there's no need for adding an empty setter, since the protocol only requires a getter.

protocol Entity: class, Codable {
    var id: String { get set }
    var version: String { get }
    var deleted: Bool { get set }
    var uid: String { get set }
    func validate() -> [String: String]
}

extension Entity {
    var version: String {
        "v0.0"
    }
    
    func validate() -> [String: String]{
        [:]
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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