简体   繁体   English

与泛型的关联类型一致的协议会产生编译器错误

[英]Protocol with associatedtype conformance with generic gives compiler error

I'm trying to make a DB mock to test some UI implementations, but compiler keeps giving me the following error: Type 'DBClientMock<T>' does not conform to protocol 'DBClient'我正在尝试制作一个 DB 模拟来测试一些 UI 实现,但编译器一直给我以下错误: Type 'DBClientMock<T>' does not conform to protocol 'DBClient'

This is my code...这是我的代码...

protocol DBClient {
    associatedtype Model
    func get(id: UUID, completion: @escaping ((Model?, Error?)) -> Void)
    func insert(_ model: Model, completion: @escaping (Error?) -> Void)
    func delete(_ model: Model, completion: @escaping (Error?) -> Void)
}

final class DBClientMock<T>: DBClient where T: Identifiable, T: Equatable {
    
    typealias Model = T
    
    private let queue: DispatchQueue
    private var modelDB = [T]()
    
    enum Error: Swift.Error {
        case notFound
    }
    
    init(queue: DispatchQueue = DispatchQueue.global()) {
        self.queue = queue
    }
    
    private func getModel(id: UUID) -> T? {
        let results = modelDB.filter({ $0.id as? UUID == id })
        guard results.count > 0 else { return nil }
        return results[0]
    }
    
    // Extension
    func get(id: UUID, completion: @escaping ((T?, Error?)) -> Void) {
        let record = getModel(id: id)
        queue.asyncAfter(deadline: .now() + .milliseconds(1500), execute: {
            if let model = record {
                completion((model, nil))
            } else {
                completion((nil, Error.notFound))
            }
        })
    }
    
    func insert(_ model: T, completion: @escaping (Error?) -> Void) {
        modelDB.append(model)
        queue.asyncAfter(deadline: .now() + .milliseconds(1000), execute: {
            completion(nil)
        })
    }
    
    func delete(_ model: T, completion: @escaping (Error?) -> Void) {
        modelDB.removeAll(where: { $0 == model })
        queue.asyncAfter(deadline: .now() + .milliseconds(800), execute: {
            completion(nil)
        })
    }
}

XCode: Version 12.4 (12D4e) Swift: 5.0 XCode:版本 12.4 (12D4e) Swift: 5.0

What am I doing wrong?我究竟做错了什么? Do I have to be more explicit with the generic type in some way?我是否必须以某种方式更明确地使用泛型类型? I tried replacing T with Model but had the same result.我尝试用Model替换T但结果相同。

Thanks for your help!谢谢你的帮助!

It doesn't conform because you declared another Error type inside the class, so everywhere where you use Error in the required methods, it uses DBClientMock.Error instead of the protocol-required Swift.Error .它不符合要求,因为您在 class 中声明了另一个Error类型,因此在所需方法中使用Error的任何地方,它都使用DBClientMock.Error而不是协议所需的Swift.Error

Either rename DBClientMock.Error to something else, or change the Error in methods to Swift.Error , like below:DBClientMock.Error重命名为其他名称,或将方法中的Error更改为Swift.Error ,如下所示:

// Extension
func get(id: UUID, completion: @escaping (T?, Swift.Error?) -> Void) {
   //...
}

func insert(_ model: T, completion: @escaping (Swift.Error?) -> Void) {
   //...
}

func delete(_ model: T, completion: @escaping (Swift.Error?) -> Void) {
   //...
}

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

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