gpt4 book ai didi

Swift:我可以拥有一个继承自协议(protocol)并对其进行约束的协议(protocol)吗?

转载 作者:行者123 更新时间:2023-11-28 07:25:56 25 4
gpt4 key购买 nike

假设我有以下协议(protocol):

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
}
}

我现在可以实现一个具体类型,它返回符合协议(protocol)的具体类型。返回的具体类型与我的其余代码无关,因为其余代码只关心它们是否符合协议(protocol)。这使我能够制作模型的“生产”和“虚拟”版本。

有没有一种方法可以更笼统地定义它,例如:

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 范例,但不一定要在“基本协议(protocol)”级别限制任何东西,因为我通常只是为我会的各种协议(protocol)类型重写这些方法签名想一起工作。

如果我没记错的话,关联类型必须是具体的,使它们的返回类型也具体,然后我就不能轻松地使用协议(protocol)类型。

对不起,如果我没有“规范”地说话。我希望我能够传达我的意图。

这可能是即将到来的 Swift 5.1 在不透明类型方面提供的,返回 -> 一些 ProtocolType 吗?

最佳答案

事实证明,不透明类型也不是答案。

我通过为管理器创建抽象基类解决了我的问题,Query 和 QueryResults 是通用结构,管理器的具体子类可以获取和返回基于协议(protocol)的数据类型。

public struct Query<T> {

var searchPredicate: NSPredicate?
var sortingBlock: ((T, T) throws -> Bool)?
var groupingSpecifier: (() -> String)?

var results: QueryResults<T>?

init(matching predicate: NSPredicate?,
sort: ((T, T) throws -> Bool)?,
groupBy: (() -> String)?) {

}
}


public struct QueryResults<T> {

public enum ChangeType: UInt {
case insert = 1
case delete
case move
case update
}

public struct Section<T> {
var items: [T]
var title: String?
}

public var sections: [Section<T>] = []

public func object(at indexPath: IndexPath) -> T? {
return nil
}
}

public class AnyObjectManager<ObjectType> {

public enum Error: Swift.Error {
case abstractImplementationRequiresOverride
}

typealias QueryDidChangeObjectBlock = ((
_ query: Query<ObjectType>,
_ didChangeObject: ObjectType,
_ atPath: IndexPath?,
_ forChangeType: QueryResults<ObjectType>.ChangeType,
_ newIndexPath: IndexPath?) -> Void)

typealias QueryDidChangeSectionBlock = ((
_ query: Query<ObjectType>,
_ didChangeSection: QueryResults<ObjectType>.Section<ObjectType>,
_ atSectionIndex: Int,
_ forChangeType: QueryResults<ObjectType>.ChangeType) -> Void)

/// get some objects matching query criteria. nil means return all
func objects(matching query: Query<ObjectType>?) -> [ObjectType] {
fatalError("Abstract implementation. You need to override this method and provide an implementation!")
}

/// get a specific object
func object(withID identifier: String) -> ObjectType? {
fatalError("Abstract implementation. You need to override this method and provide an implementation!")
}

/// deletes the objects. Does it commit that to disk?
func remove(_ objects: [ObjectType]) {
fatalError("Abstract implementation. You need to override this method and provide an implementation!")
}

/// creates a new object but does not save it.
func create() -> ObjectType {
fatalError("Abstract implementation. You need to override this method and provide an implementation!")
}

/// this is basically to mimic the functionality of a fetched results controller...
func monitorQuery(_ query: Query<ObjectType>,
willChangeBlock: ((_ query: Query<ObjectType>) -> Void)?,
didChangeObjectBlock: QueryDidChangeObjectBlock?,
didChangeSectionBlock: QueryDidChangeSectionBlock?,
didFinishChangesBlock:((_ query: Query<ObjectType>) -> Void)?) {
fatalError("Abstract implementation. You need to override this method and provide an implementation!")
}
/// and this is to stop monitoring that.
func stopMonitoringQuery() {
fatalError("Abstract implementation. You need to override this method and provide an implementation!")
}

public func saveChanges() throws {
fatalError("Abstract implementation. You need to override this method and provide an implementation!")
}

public func discardChanges() throws {
fatalError("Abstract implementation. You need to override this method and provide an implementation!")
}
}

关于Swift:我可以拥有一个继承自协议(protocol)并对其进行约束的协议(protocol)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56602522/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com