[英]How to create array of generic associated type protocol in swift?
Better to ask with example. 最好举个例子。 So its table sections and rows
所以它的表部分和行
First created a protocol which needs to be implemented by all rows which has an associated type, must be given by caller to tell while defining row. 首先创建一个协议,该协议必须由具有关联类型的所有行实现,调用方必须在给定行时告诉它。
protocol RowElementProtocol {
associatedtype ElementType
var cellIdentifier: String {get set}
var cellType: ElementType {get set}
}
So creating a generic row struct here 所以在这里创建一个通用的行结构
struct GenericRow <T>: RowElementProtocol {
var cellIdentifier = "cell"
var cellType: T
/// Some Other Properties
init(cellIdentifier: String = "cell", cellType: T) {
self.cellIdentifier = cellIdentifier
self.cellType = cellType
}
}
Creating a different row struct here 在这里创建一个不同的行结构
struct DifferentRow<T>: RowElementProtocol {
var cellIdentifier = "cell"
var cellType: T
/// Some Different Properties other then generic
}
Now creating a section which can have any kind of rows 现在创建一个可以包含任何行的节
struct Section<T: RowElementProtocol> {
var rows = 1
var rowElements: [T]
}
Everything is fine here, Problem arises when I want to initialise an array of sections 一切都很好,当我想初始化一个节数组时出现问题
let sections = [Section<T: RowElementProtocol>]()
Compiler is not allowing me to initialise. 编译器不允许我初始化。 Its showing ">' is not a postfix unary operator".
其显示的“>'不是后缀一元运算符”。
You need to tell the compiler what the implemented type of T is 您需要告诉编译器T的实现类型是什么
let sections = [Section<GenericRow<String>>]()
or like this 或像这样
typealias SectionType = Section<GenericRow<String>>
let sections = [SectionType]()
Let's have a look at the consequences of the compiler allowing you to create such an array. 让我们看一下允许您创建此类数组的编译器的结果。
You could do something like this: 您可以执行以下操作:
var sections = [Section<T: RowElementProtocol>]()
var sec1 = Section<GenericRow<String>>()
var sec2 = Section<DifferentRow<Int>>()
sections.append(sec1)
sections.append(sec2)
let foo = sections[0] // how can the compiler know what type this is?
See the problem now? 现在看到问题了吗? "Well,
foo
can just be of type Section<T: RowElementProtocol>
" you might say. 您可能会说
Section<T: RowElementProtocol>
“好吧, foo
可以是Section<T: RowElementProtocol>
类型。” Okay, let's suppose that's true: 好吧,让我们假设这是真的:
foo.rowElements[0].cellType // what the heck is the type of this?
The compiler has no idea. 编译器不知道。 It only knows that
foo.rowElements[0]
is "some type that conforms to RowElementProtocol
but cellType
could be anything. 它只知道
foo.rowElements[0]
是“符合RowElementProtocol
某种类型,但是cellType
可以是任何类型。
"Okay, why not just use Any
for that type?" “好吧,为什么不只对这种类型使用
Any
?” you might ask. 你可能会问。 The compiler could do this, but that makes your generics pointless, doesn't it?
编译器可以做到这一点,但这使您的泛型毫无意义,不是吗?
If you want to make your generics pointless, you can do what's called "type erasure", by creating the types AnyRowElement
and AnySection
: 如果你想使你的仿制药没有意义的,你可以做什么叫做“类型擦除”,通过创建类型
AnyRowElement
和AnySection
:
struct AnyRowElement : RowElementProtocol {
var cellIdentifier: String
var cellType: Any
typealias ElementType = Any
init<T: RowElementProtocol>(_ x: T) {
self.cellIdentifier = x.cellIdentifier
self.cellType = x.cellType
}
}
struct AnySection {
var rows: Int
var rowElements: [AnyRowElement]
init<T: RowElementProtocol>(_ x: Section<T>) {
self.rows = x.rows
self.rowElements = x.rowElements.map(AnyRowElement.init)
}
}
let sections: [AnySection] = [AnySection(sec1), AnySection(sec2)]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.