Swift:通用集合的集合

杰拉尔德

我有一个基类ItemBase和一个CollectionBase带有type项的类ItemBase

我得到这个两个类ItemBase-PersonItemAnimalItem

我从CollectionBase带有适当项目的两个类中-PersonCollectionAnimalCollection

然后创建一个类型为CollectionBase-的数组ItemBase

现在,我想将PersonCollection附加AnimalCollection到数组,但是出现以下错误:

“无法将类型为“ PersonCollection”的值分配为类型为“ DataCollection”

如何定义可以基于CollectionBase-附加项的collection-array ItemBase

class ItemBase {
}

class CollectionBase<T: ItemBase> {
  var Items = [T]()
}

class PersonItem: ItemBase {
}

class PersonCollection: CollectionBase<PersonItem> {
}

class AnimalItem: ItemBase {
}

class AnimalCollection: CollectionBase<AnimalItem> {
}

var collection = [CollectionBase<ItemBase>]()

// Error: Cannot assign value of type 'PersonCollection' to type 'DataCollection<ItemBase>
collection.append(PersonCollection())
// Error: Cannot assign value of type 'AnimalCollection' to type 'DataCollection<ItemBase>
collection.append(AnimalCollection())
亚历克斯·布朗

首先,您的示例包含一些关于编译器无法正确接受的类型系统的矛盾声明。

对于那个“啊哈时刻”,请阅读Wikipedia上的方差和逆方差否则,请继续阅读。


您的示例在此处失败的原因是

var collection = [CollectionBase<ItemBase>]()

定义一个类数组,您可以使用ItemsItemBase类的项目访问和更新member属性。

然后,您尝试添加PersonCollection()违反此要求的数组元素-不允许将ItemBase添加到其Items成员。


其次,因为

PersonCollection继承自ItemBase

您认为以下内容是正确的:

SomeGeneric <PersonCollection>继承自SomeGeneric <ItemBase>

尽管这对您来说可能是非常合理的,但快速的语言中没有什么可以做到的。

您可能在这里合理地指出,swift集合类似乎可以管理此OK-如下所示:

class ItemBase {
}

class PersonItem: ItemBase {
}

class AnimalItem: ItemBase {
}

var collection = [Array<ItemBase>]()

collection.append([PersonItem]())

它可以执行此操作,但不幸的是,这样做是因为swift语言对诸如的内置集合类型具有特殊的规则Array据我所知,您不能仅使用快速代码独立实现Array。


那么如何处理呢?

在解决设计中的上述矛盾之前,您不能。但是,我认为这些功能只是根据您所使用的语言来解决问题的方式的伪像。

您可以使用swift的内置Array类。

或者,您可以定义一个不同的继承层次结构,该继承层次结构不是通用的:

例如-在基础上使用协议(或类),该协议肯定适用于ItemBase对象(无关联的类型要求)。

protocol ItemCollection {
    var items:[ItemBase] { get }
}

class ThingCollection<Thing:ItemBase>:ItemCollection {
    var things:[Thing] = []
    var items:[ItemBase] {
        return things
    }
}

typealias PersonCollection = ThingCollection<PersonItem>


var itemCollection:[ItemCollection] = []

itemCollection.append(PersonCollection())

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章