构建Swift代码时出现此错误:
Cannot invoke 'insert' with an argument list of type '(BaseCellData, at: Int)' on the row
当我运行以下代码时:
public class CellDataCollection<T: BaseCellData> {
private var data = [T]()
func populate(from data: [T]) {
self.data = data
let firstObjectIsHeader = data.first?.isHeader ?? false
if !firstObjectIsHeader {
let newEmptyHeader = BaseCellData(isEmptyHeader: true)
self.data.insert(newEmptyHeader, at: 0)
}
// ...
}
}
我认为因为T是一个BaseCellData,所以可以将一个新的BaseCellData实例添加到T的数组中。可能有什么问题?
答案 0 :(得分:0)
强制施放newEmptyHeader
为T
符合我的机器。
public class BaseCellData {
public var isEmptyHeader = false
public var isHeader = true
public init(isEmptyHeader: Bool) {
self.isEmptyHeader = isEmptyHeader
}
}
public class CellDataCollection<T: BaseCellData> {
private var data = [T]()
func populate(from data: [T]) {
self.data.append(contentsOf:data)
let firstObjectIsHeader = data.first?.isHeader ?? false
if !firstObjectIsHeader {
let newEmptyHeader = BaseCellData(isEmptyHeader: true)
// Safer approach
if let newEmptyHeader = newEmptyHeader as? T {
self.data.insert(newEmptyHeader, at: 0)
}
}
}
}
答案 1 :(得分:0)
您的T数组是一种特定类型,其中BaseCellData更通用。
例如,假设你有这些课程:
class Animal {}
class Dog: Animal {}
class Cat: Animal {}
你创造了一系列狗,显然你不能添加猫或动物
var dogs = [Dog]
dogs.append(Cat()) // Not allowed
dogs.append(Animal()) // Also not allowed
所以如果你有一个通用的:
class AnimalCollection<T:Animal> {
var animals: [T]
}
然后,如果您创建一个集合,则T的类型是您定义为泛型类型的任何类型。所以:
let dogCollection: AnimalCollection<Dog>
阵列属于Dog类型,正如我们在添加动物或猫之前看到的那样是不允许的。
答案 2 :(得分:0)
我通过向所有实现BaseCellType的子类添加构造函数来解决它。这允许我创建一个T实例而不是BaseCellType:
public class CellDataCollection<T: BaseCellData> {
func dataWithLeadingEmptyHeader(from data: [T]) -> [T] {
var newData = data
let firstObjectIsHeader = data.first?.isHeader ?? false
if !firstObjectIsHeader {
let newEmptyHeader = T(isEmptyHeader: true)
newData.insert(newEmptyHeader, at: 0)
}
return newData
}
func populate(from data: [T]) {
self.data = dataWithLeadingEmptyHeader(from: data)
// ...
}
}
我的基类现在有两个新的内容:
public class BaseCellData: XXX {
required override public init(isEmptyHeader: Bool) {
super.init()
isHeader = true
self.isEmptyHeader = isEmptyHeader
}
public override init() {
super.init()
}
}
和子类现在有一个新的init:
public class SelectIconCellData: BaseCellData {
var iconName: String = ""
init(text: String, imageName: String) {
super.init()
// ...
}
required public init(isEmptyHeader: Bool) {
super.init(isEmptyHeader: isEmptyHeader)
}
}