【发布时间】:2019-10-29 08:21:10
【问题描述】:
假设我有以下协议:
protocol RateableItem {
var identifier: String { get } // placeholder. This could be a lot of properties
var name: String { get set }
var rating: Int { get set }
}
protocol RateableItemManager {
/// get some objects matching query criteria
func objects(matching query: RateableItemQuery) -> [RateableItem]
/// get a specific object
func object(withID identifier: String) -> RateableItem?
/// persists them
func save(_ object: RateableItem) throws
/// deletes the objects.
func delete(_ objects: [RateableItem])
/// creates a new object.
func create() -> RateableItem
}
和
struct RateableItemQuery {
let searchPredicate: NSPredicate? // nil means all
let sortingBlock: ((RateableItem, RateableItem) throws -> Bool)?
let groupingSpecifier: (() -> String)?
init(matching predicate: NSPredicate? = nil,
sort: ((RateableItem, RateableItem) throws -> Bool)? = nil,
groupBy: (() -> String)? = nil) {
self.searchPredicate = predicate
self.sortingBlock = sort
self.groupingSpecifier = groupBy
}
}
我现在可以实现 this 的具体类型,它返回符合协议的具体类型。返回的具体类型与我的其余代码无关,因为其余代码只关心它们是否符合协议。这使我能够制作模型的“生产”和“虚拟”版本。
有没有办法可以更一般地定义这个,例如:
struct Query<T> {
let searchPredicate: NSPredicate? // nil means all
let sortingBlock: ((T, T) throws -> Bool)?
let groupingSpecifier: (() -> String)?
init(matching predicate: NSPredicate? = nil,
sort: ((T, T) throws -> Bool)? = nil,
groupBy: (() -> String)? = nil) {
self.searchPredicate = predicate
self.sortingBlock = sort
self.groupingSpecifier = groupBy
}
}
这样
struct RateableItemQuery: Query<RateableItem> {}
和
protocol ItemManager<T> {
func objects(matching query: Query<T>) -> [T]
func object(withID identifier: String) -> T?
func save(_ object: T) throws
func delete(_ objects: [T])
func create() -> T
}
和
protocol RateableItemManager: ItemManager<RateableItem>
因为我想使用这个 API 范例,但不一定想在“基本协议”级别限制任何东西,因为我经常只是为我想要的各种协议类型重写这些方法签名想合作。
如果我没记错的话,关联类型必须是具体的,使它们的返回类型也具体,然后我就不能轻松地使用协议类型。
对不起,如果我没有说“规范”。我希望我能够传达我的意图。
这可能是即将到来的 Swift 5.1 提供的不透明类型,返回 -> 一些 ProtocolType 吗?
【问题讨论】:
-
不透明类型是您的答案。
标签: swift generics protocols swift-protocols