具有通用功能的相关类型协议的协议
Protocol with associatedtype Protocol for Generic functions
是否可以在另一个协议的通用功能中提供确认协议?
我试着让它像这样工作,但是不可能,或者我犯了一些错误。
我的代码:
protocol DataModelProtocol {
associatedtype ObjectProtocol: Protocol
func fetchObjects<T: ObjectProtocol>() -> [T]?
func fetch<T: ObjectProtocol>(object: T) -> T?
func delete<T: ObjectProtocol>(allObjectOf type: T.Type)
func insert<T: ObjectProtocol>(_ object: T)
func save<T: ObjectProtocol>(_ object: T)
func update<T: ObjectProtocol>(_ object: T)
func delete<T: ObjectProtocol>(_ object: T)
}
错误信息:
inheritance from non-protocol, non-class type 'Self.ObjectProtocol'
Image of Xcode error
它只能这样工作,但我想让它更灵活:
protocol DataModelProtocol {
typealias ObjectProtocol = NSManagedObject
...
}
如果你想要符合另一个协议的通用功能,只需简单地创建一个符合该协议的associatedType
of T
,不需要额外制作ObjectProtocol
:
protocol DataModelProtocol {
associatedtype T: Protocol
func fetchObjects<T>() -> [T]?
func fetch<T>(object: T) -> T?
func delete<T>(allObjectOf type: T.Type)
func insert<T>(_ object: T)
func save<T>(_ object: T)
func update<T>(_ object: T)
func delete<T>(_ object: T)
}
如果您将 return 类型的责任交给对象 类 本身,这可能会更容易。
您将需要两个协议,但它会避免混合协议和泛型:
// The first protocol is for the base class of data objects
protocol DataProtocol
{}
// The protocol provides the "typed" equivalents of the model's
// data manipulation methods.
// By using an extension to DataProtocol, this only needs to
// be done once for all models and data objects.
extension DataProtocol
{
static func fetchObjects(from model:DataModelProtocol) -> [Self]?
{ return model.fetchObjects(object: Self.self) as! [Self]? }
static func fetch(from model:DataModelProtocol) -> Self?
{ return model.fetch(object: Self.self) as! Self? }
// ...
}
// The second protocol is for the data models
// It requires implementation of the data manipulation methods
// using the general "DataProtocol" rather than any specific class
// The actual instances it produces must be of the appropriate class
// however because they will be type casted by the DataProtocol's
// default methods
protocol DataModelProtocol
{
func fetchObjects(object:DataProtocol.Type) -> [DataProtocol]?
func fetch(object:DataProtocol.Type) -> DataProtocol?
// ... and so on
}
...
这是一个如何使用协议的简单(幼稚)示例。 (我故意选择不使用核心数据来说明解决方案的通用性)
...
// The base class (or each one) can be assigned the DataProtocol
// (it doesn't add any requirement)
class LibraryObject : DataProtocol
{}
class Author: LibraryObject
{
var name = ""
}
class Book: LibraryObject
{
var title = ""
}
// This is a simple class that implements a DataModelProtocol
// in a naive (and non-core-data way)
struct LibraryModel:DataModelProtocol
{
var authors:[Author] = [ Author(), Author() ]
var books:[Book] = [ Book(), Book(), Book(), Book(), Book() ]
func fetchObjects(object: DataProtocol.Type) -> [DataProtocol]?
{
return object == Book.self ? books
: object == Author.self ? authors
: nil
}
func fetch(object:DataProtocol.Type) -> DataProtocol?
{ return nil }
}
...
使用协议将与您的方法有点不同,因为您将从对象 类 开始,而不是将它们作为参数传递给模型
...
var library = LibraryModel()
let allBooks = Book.fetchObjects(from:library) // this almost reads like english
是否可以在另一个协议的通用功能中提供确认协议? 我试着让它像这样工作,但是不可能,或者我犯了一些错误。
我的代码:
protocol DataModelProtocol {
associatedtype ObjectProtocol: Protocol
func fetchObjects<T: ObjectProtocol>() -> [T]?
func fetch<T: ObjectProtocol>(object: T) -> T?
func delete<T: ObjectProtocol>(allObjectOf type: T.Type)
func insert<T: ObjectProtocol>(_ object: T)
func save<T: ObjectProtocol>(_ object: T)
func update<T: ObjectProtocol>(_ object: T)
func delete<T: ObjectProtocol>(_ object: T)
}
错误信息:
inheritance from non-protocol, non-class type 'Self.ObjectProtocol'
Image of Xcode error
它只能这样工作,但我想让它更灵活:
protocol DataModelProtocol {
typealias ObjectProtocol = NSManagedObject
...
}
如果你想要符合另一个协议的通用功能,只需简单地创建一个符合该协议的associatedType
of T
,不需要额外制作ObjectProtocol
:
protocol DataModelProtocol {
associatedtype T: Protocol
func fetchObjects<T>() -> [T]?
func fetch<T>(object: T) -> T?
func delete<T>(allObjectOf type: T.Type)
func insert<T>(_ object: T)
func save<T>(_ object: T)
func update<T>(_ object: T)
func delete<T>(_ object: T)
}
如果您将 return 类型的责任交给对象 类 本身,这可能会更容易。
您将需要两个协议,但它会避免混合协议和泛型:
// The first protocol is for the base class of data objects
protocol DataProtocol
{}
// The protocol provides the "typed" equivalents of the model's
// data manipulation methods.
// By using an extension to DataProtocol, this only needs to
// be done once for all models and data objects.
extension DataProtocol
{
static func fetchObjects(from model:DataModelProtocol) -> [Self]?
{ return model.fetchObjects(object: Self.self) as! [Self]? }
static func fetch(from model:DataModelProtocol) -> Self?
{ return model.fetch(object: Self.self) as! Self? }
// ...
}
// The second protocol is for the data models
// It requires implementation of the data manipulation methods
// using the general "DataProtocol" rather than any specific class
// The actual instances it produces must be of the appropriate class
// however because they will be type casted by the DataProtocol's
// default methods
protocol DataModelProtocol
{
func fetchObjects(object:DataProtocol.Type) -> [DataProtocol]?
func fetch(object:DataProtocol.Type) -> DataProtocol?
// ... and so on
}
... 这是一个如何使用协议的简单(幼稚)示例。 (我故意选择不使用核心数据来说明解决方案的通用性) ...
// The base class (or each one) can be assigned the DataProtocol
// (it doesn't add any requirement)
class LibraryObject : DataProtocol
{}
class Author: LibraryObject
{
var name = ""
}
class Book: LibraryObject
{
var title = ""
}
// This is a simple class that implements a DataModelProtocol
// in a naive (and non-core-data way)
struct LibraryModel:DataModelProtocol
{
var authors:[Author] = [ Author(), Author() ]
var books:[Book] = [ Book(), Book(), Book(), Book(), Book() ]
func fetchObjects(object: DataProtocol.Type) -> [DataProtocol]?
{
return object == Book.self ? books
: object == Author.self ? authors
: nil
}
func fetch(object:DataProtocol.Type) -> DataProtocol?
{ return nil }
}
... 使用协议将与您的方法有点不同,因为您将从对象 类 开始,而不是将它们作为参数传递给模型 ...
var library = LibraryModel()
let allBooks = Book.fetchObjects(from:library) // this almost reads like english