关联类型符合泛型的协议会产生编译器错误
Protocol with associatedtype conformance with generic gives compiler error
我正在尝试制作一个数据库模拟来测试一些 UI 实现,但编译器一直给我以下错误:
Type 'DBClientMock<T>' does not conform to protocol 'DBClient'
这是我的代码...
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({ [=10=].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: { [=10=] == model })
queue.asyncAfter(deadline: .now() + .milliseconds(800), execute: {
completion(nil)
})
}
}
XCode:版本 12.4 (12D4e)
Swift: 5.0
我做错了什么?我是否必须以某种方式更明确地使用泛型类型?我尝试用 Model
替换 T
但结果相同。
感谢您的帮助!
它不符合要求,因为您在 class 中声明了另一个 Error
类型,因此在所需方法中使用 Error
的任何地方,它都使用 DBClientMock.Error
而不是协议要求的 Swift.Error
.
要么将 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) {
//...
}
我正在尝试制作一个数据库模拟来测试一些 UI 实现,但编译器一直给我以下错误:
Type 'DBClientMock<T>' does not conform to protocol 'DBClient'
这是我的代码...
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({ [=10=].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: { [=10=] == model })
queue.asyncAfter(deadline: .now() + .milliseconds(800), execute: {
completion(nil)
})
}
}
XCode:版本 12.4 (12D4e) Swift: 5.0
我做错了什么?我是否必须以某种方式更明确地使用泛型类型?我尝试用 Model
替换 T
但结果相同。
感谢您的帮助!
它不符合要求,因为您在 class 中声明了另一个 Error
类型,因此在所需方法中使用 Error
的任何地方,它都使用 DBClientMock.Error
而不是协议要求的 Swift.Error
.
要么将 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) {
//...
}