我正在尝试编写一个协议,允许我在我的应用程序中版本模型。为了做到这一点,我编写了以下VersionManager
。
class VersionManager<Type: Decodable> {
private var database: Database
init(database: Database) {
self.database = database
}
var versions: [Type] {
return []
}
}
之后,我编写了一个可以添加到模型中的协议:
protocol Versionable {
}
extension Versionable {
private var manager: VersionManager<Restaurant> {
return VersionManager<Restaurant>(database: Database.shared)
}
public var versions: [Restaurant] {
return manager.versions
}
}
现在,我面临的问题是,我试图动态地传递类型,而不是硬编码,就像我现在对于
Restaurant
所做的那样。所以我试着把协议改成:
protocol Versionable {
var kind: Decodable.Type { get }
}
然后我想把
kind
传递到VersionManager
。但是,当我尝试Xcode抛出这个错误时:Expected '>' to complete generic argument list
。还有别的办法吗?
最佳答案
如果要在protocol
中使用泛型,则需要使用associatedtype
protocol Versionable {
associatedtype Model: Decodable
}
extension Versionable {
private var manager: VersionManager<Model> {
return VersionManager<Model>(database: Database.shared)
}
public var versions: [Model] {
return manager.versions
}
}
要实现
Versionable
协议的模型必须解决以下类型:struct SomeModel: Versionable {
typealias Model = Int
}
SomeModel().versions // [Int]
我猜您的示例中的
Restaurant
指的是实现Versionable
的模型。在这种情况下,您只需在协议扩展内使用Self
引用即可:protocol Versionable: Decodable {
}
extension Versionable {
private var manager: VersionManager<Self> {
return VersionManager<Self>(database: Database.shared)
}
public var versions: [Self] {
return manager.versions
}
}
struct SomeModel: Versionable {}
SomeModel().versions // [SomeModel]
请注意,
Versionable
协议现在需要Decodable
一致性,因为VersionManager<Type: Decodable>
通用约束。