Swift 无法调用';插入';具有BaseCellData类型的参数列表
我在生成Swift代码时遇到此错误:Swift 无法调用';插入';具有BaseCellData类型的参数列表,swift,generics,Swift,Generics,我在生成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]) {
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)
}
// ...
}
}
公共类CellDataCollection{
私有var数据=[T]()
func填充(从数据:[T]){
self.data=数据
设FirstObjectsHeader=data.first?.isHeader??false
如果!第一个目标领导者{
让newEmptyHeader=BaseCellData(isEmptyHeader:true)
self.data.insert(newEmptyHeader,地址:0)
}
// ...
}
}
我想既然T是BaseCellData,那么将BaseCellData的一个新实例添加到T数组中应该是可以的。有什么问题吗?强制转换
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)
}
}
}
}
公共类BaseCellData{
公共变量isEmptyHeader=false
公共变量isHeader=true
公共初始化(isEmptyHeader:Bool){
self.isEmptyHeader=isEmptyHeader
}
}
公共类CellDataCollection{
私有var数据=[T]()
func填充(从数据:[T]){
self.data.append(contentsOf:data)
设FirstObjectsHeader=data.first?.isHeader??false
如果!第一个目标领导者{
让newEmptyHeader=BaseCellData(isEmptyHeader:true)
//更安全的方法
如果让newEmptyHeader=newEmptyHeader为?T{
self.data.insert(newEmptyHeader,地址:0)
}
}
}
}
您的T数组是一种特定类型,其中as 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]
}
然后,如果您创建一个集合,则T的类型是您定义为泛型类型的任何类型。因此:
let dogCollection: AnimalCollection<Dog>
let dogCollection:动物采集
数组是Dog类型的,正如我们之前看到的,不允许向其中添加动物或猫。我通过向实现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)
// ...
}
}
子类现在有一个新的init:
public class SelectIconCellData: BaseCellData {
var iconName: String = ""
init(text: String, imageName: String) {
super.init()
// ...
}
required public init(isEmptyHeader: Bool) {
super.init(isEmptyHeader: isEmptyHeader)
}
}
除非如果T不是
BaseCellData
,否则这将导致运行时异常。这样就使得泛型没用了。是的,我同意。在泛型中使用特定类型会使泛型整体失败。不幸的是,在运行时崩溃我删除了强制展开。但我仍然不知道你正在试图实现什么。也许你需要再看看泛型来解决这个问题,@TristanBurnside提到是的,我知道我在代码中哪里错了。我试图将基类插入到特定T类型的列表中。我已经重新考虑了我的解决方案。
public class SelectIconCellData: BaseCellData {
var iconName: String = ""
init(text: String, imageName: String) {
super.init()
// ...
}
required public init(isEmptyHeader: Bool) {
super.init(isEmptyHeader: isEmptyHeader)
}
}