Swift 无法调用';插入';具有BaseCellData类型的参数列表

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]) {

我在生成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)
        }
        // ...
    }
}
公共类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)
    }
}