[英]Constrain protocol's associated type itself
I'm trying to create generic CollectionView datasource. 我正在尝试创建通用的CollectionView数据源。 I have two protocols, first - some abstract cell, the second indicates that conforming class could be presented by some abstract cell and should contain only associated type referencing that cell.
我有两个协议,第一个-一个抽象单元格,第二个表明某个抽象单元格可以表示符合类,并且应该只包含引用该单元格的关联类型。 Their implementation could look like this:
它们的实现可能如下所示:
protocol EntityPresentingCell {
// entity that should be presented in this cell
associatedtype T
static var CellReuseID: String { get }
// takes object and fill UI with data
func populate(with object: T)
}
protocol CellPresentable {
// cell that should present this entity
// I need to constrain it
associatedtype Cell: EntityPresentingCell // where Cell.T == Self
}
class CollectionViewDataSource<T: CellPresentable>: NSObject, UICollectionViewDataSource {
var items: [T]
init(items: [T]) {
self.items = items
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return items.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: T.Cell.CellReuseID, for: indexPath)
// compiler error here since, obviously, T.Cell.T not constrained to T itself
(cell as! T.Cell).populate(with: items[indexPath.item])
return cell
}
}
At the point of usage it could look like this: 在使用时,它可能看起来像这样:
class SomeEntity: CellPresentable {
typealias Cell = SomeEntityCell
var someValue = "someValue"
}
class SomeEntityCell: EntityPresentingCell {
static var CellReuseID: String = "SomeID"
@IBOutlet weak var label: UILabel!
func populate(with object: SomeEntity) {
label.text = object.someValue
}
}
The problem with this code is that I can not constrain (and thus be sure at compile time that) CellPresentable.Cell.T to be equal to CellPresentable itself (like in example). 这段代码的问题是,我无法约束CellPresentable.Cell.T(因此确保在编译时确保它)等于CellPresentable本身(例如示例)。 It is clearly seen with compiler error.
可以清楚地看到编译器错误。
The goal is to make pure compile-time all-sufficient code that could prove that item is presentable by given cell (again, at compile time) and I don't want to force downcasts, or any other run-time checks. 目标是制作纯粹的编译时全能代码,以证明该项目可以在给定的单元格中显示出来(再次在编译时),而我不想强制向下转换或进行任何其他运行时检查。
Is it possible? 可能吗? If so, how?
如果是这样,怎么办?
UPD: David Rodrigues answer works, but it means that mismatch (T.Cell.T != T)
will be revealed only when I'm about to create CollectionViewDataSource
. UPD: David Rodrigues的答案有效,但这意味着不匹配
(T.Cell.T != T)
仅在我要创建CollectionViewDataSource
时才会显示。 I want it to happen exactly when I define my entity's conformance to EntityPresentingCell
protocol. 我希望在定义我的实体对
EntityPresentingCell
协议的符合性时发生。 In other words, compiler should complain when I write something like 换句话说,当我写类似的东西时,编译器应该抱怨
class SomeEntity: CellPresentable {
typealias Cell = SomeWrongEntityCell
var someValue = "someValue"
}
but not when I create CollectionViewDataSource
instance. 但是当我创建
CollectionViewDataSource
实例时却没有。 It's entity responsibility to ensure cell type, not the creator of CollectionViewDataSource
. 确保单元格类型是实体的责任,而不是
CollectionViewDataSource
的创建者。
You can now add the where Cell.T == Self
constraint to the associated type, so you can indeed now just say: 现在,您可以将
where Cell.T == Self
约束添加到关联的类型,因此,您现在确实可以说:
protocol CellPresentable {
associatedtype Cell : EntityPresentingCell where Cell.T == Self
}
Currently, it's not possible to add any further constraints to associated types besides what they are required to conform to. 当前,除了需要遵守的约束之外,不可能对关联的类型添加任何其他约束。
However, now that SE-0142: Permit where clauses to constrain associated types has been accepted, being able to add where
clauses to associated types will be possible in a future version of Swift. 但是,现在SE-0142:允许约束关联类型的where子句已被接受,在以后的Swift版本中,可以在关联类型中添加
where
子句。
You should just be able to say: 您应该只能说:
protocol CellPresentable {
associatedtype Cell : EntityPresentingCell where Cell.T == Self
}
Although until this is implemented, David's solution of adding the generic constraint where T.Cell.T == T
is probably about as good as you're going to get. 尽管在实现之前, David的添加通用约束(
where T.Cell.T == T
的解决方案)的解决方案可能与您将要获得的效果where T.Cell.T == T
。
您可以约束T.Cell.T
等于T
class CollectionViewDataSource<T: CellPresentable>: NSObject, UICollectionViewDataSource where T.Cell.T == T
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.