我正在尝试在Swift中继承一个泛型类,但无论我做什么,编译器都会抱怨,或者更糟糕的是,segfaulting。
这是我编写它的最接近的,但后来我无法创建子类的实例,因为编译器由于某种原因无法推断出T
是什么。
protocol GenericDataSourceCellProtocol {
associatedtype ModelType
var model: ModelType? {get set}
}
struct MyCellState {}
class MyCell: UITableViewCell, GenericDataSourceCellProtocol {
var model: MyCellState?
}
class Generic2DDataSource<U, T>
where U:GenericDataSourceCellProtocol, U:UITableViewCell, T == U.ModelType {
let items: [[T]]
init (items: [[T]]) {
self.items = items
}
}
class SubclassedDataSource: Generic2DDataSource<MyCell, MyCellState> {}
let state = MyCellState()
let items = [[state]]
let datasource = SubclassedDataSource(items: items)
// cannot convert value of type '[Array<MyCellState>]' to expected argument type '[[T]]'
有没有办法让这项工作?我错过了什么?
答案 0 :(得分:1)
这里有很多东西,非常简单的Swift类型系统。但是,这是你想要的吗?
protocol GenericDataSourceCellProtocol {
associatedtype ModelType
var model: ModelType? {get set}
}
struct MyCellState {}
class MyCell: UITableViewCell, GenericDataSourceCellProtocol {
typealias ModelType = MyCellState
var model: MyCellState?
}
class Generic2DDataSource<U> where U: GenericDataSourceCellProtocol, U: UITableViewCell {
typealias T = U.ModelType
let items: [[T]]
init(items: [[T]]) {
self.items = items
}
}
class SubclassedDataSource: Generic2DDataSource<MyCell> {
}
let state = MyCellState()
let items = [[state]]
let datasource = SubclassedDataSource(items: items)
并且,我认为你所拥有的在技术上应该是有效的,因为我发现如果我将你的代码更改为此,它将使错误消失:
protocol GenericDataSourceCellProtocol {
associatedtype ModelType
var model: ModelType? {get set}
}
struct MyCellState {}
class MyCell: UITableViewCell, GenericDataSourceCellProtocol {
typealias ModelType = MyCellState
var model: ModelType?
}
class Generic2DDataSource<U, T> where U: GenericDataSourceCellProtocol, U: UITableViewCell, T == U.ModelType {
let items: [Array<U.ModelType>]
init(items: [Array<U.ModelType>]) {
self.items = items
}
func thing() -> T {
let value = items[0][0]
return value
}
}
class SubclassedDataSource: Generic2DDataSource<MyCell, MyCellState> {
}
注意我在基类中添加了一个函数thing
。我这样做是因为在Xcode中你可以选择+点击变量value
,它会告诉你编译器确定它的类型。在这种情况下,value
类型为T
,即使我将items
指定为[Array<U.ModelType>]
。它们应该是相同的,因为T == U.ModelType
但由于某种原因它在子类编译期间无法解决这个问题。
基于你所拥有的,我认为T
并不是必需的,因为你在U和T之间形成了一种关系。简单地将U作为通用参数就足够了,就像在我的第一个代码块。