Скажем, у меня есть следующие протоколы:
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
}
}
Теперь я могу реализовать конкретный тип этого, который возвращает конкретные типы, которые соответствуют протоколу.Конкретные типы, которые возвращаются, не имеют отношения к остальной части моего кода, потому что остальная часть кода заботится только о том, чтобы они соответствовали протоколу.Это позволяет мне делать «производственные» и «фиктивные» версии моделей.
Есть ли способ, которым я могу определить это более широко, например:
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?