Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift:通用集合的集合_Swift_Generics - Fatal编程技术网

Swift:通用集合的集合

Swift:通用集合的集合,swift,generics,Swift,Generics,我有一个基类ItemBase和一个类CollectionBase,其中包含ItemBase类型的项 我从这个itemsbase-PersonItem和AnimalItem派生出两个类 我从CollectionBase中派生了两个类,其中包含适当的项-PersonCollection和AnimalCollection 然后我创建了一个类型为CollectionBase-ItemBase的数组 现在我想将PersonCollection和AnimalCollection附加到数组中,但我得到以下错误

我有一个基类
ItemBase
和一个类
CollectionBase
,其中包含
ItemBase
类型的项

我从这个
itemsbase
-
PersonItem
AnimalItem
派生出两个类

我从
CollectionBase
中派生了两个类,其中包含适当的项-
PersonCollection
AnimalCollection

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

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

“无法将“PersonCollection”类型的值分配给类型 “数据收集”

如何定义集合数组,以便根据
CollectionBase
-
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())
class项目库{
}
类集合库{
变量项=[T]()
}
类personite:ItemBase{
}
类PersonCollection:CollectionBase{
}
类AnimalItem:ItemBase{
}
类动物集合:集合库{
}
var collection=[CollectionBase]()
//错误:无法将“PersonCollection”类型的值分配给“DataCollection”类型
collection.append(PersonCollection())
//错误:无法将“AnimalCollection”类型的值分配给“DataCollection”类型
collection.append(AnimalCollection())

为什么需要额外的间接寻址?问题是:

class ItemBase {
}

class PersonItem: ItemBase {
}

class AnimalItem: ItemBase {
}

var collection = [ItemBase]()
collection.append(PersonItem())
collection.append(AnimalItem())
或:

也有可能:

class ItemBase {
}

class PersonItem: ItemBase {
}

class AnimalItem: ItemBase {
}

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

class PersonCollection: CollectionBase<PersonItem> {
}

class AnimalCollection: CollectionBase<AnimalItem> {
}

let personCollection = PersonCollection()
personCollection.Items.append(PersonItem())

首先,您的示例包含一些编译器(正确地)无法接受的关于类型系统的矛盾语句

对于“啊哈时刻”,请继续阅读。否则,请继续阅读


你的例子在这里失败的原因是

var collection = [CollectionBase<ItemBase>]()
它确实如此,但不幸的是它这样做了,因为swift语言对内置集合类型(如
数组
)有特殊的规则。您无法仅使用swift代码独立实现数组


那么如何处理呢

在解决设计中的上述不一致之处之前,您不能。然而,我假设这些特性只是您在给定语言的情况下如何处理问题的人工制品

您可以使用swift的内置数组类

或者,您可以定义一个不同的继承层次结构,该继承层次结构在基础上不是泛型的:

例如,在基础上使用一个协议(或类),该协议肯定适用于ItemBase对象(没有相关的类型要求)

协议项集合{
变量项:[ItemBase]{get}
}
类ThingCollection:ItemCollection{
变量things:[事物]=[]
变量项:[ItemBase]{
归还物品
}
}
typealias PersonCollection=ThingCollection
var itemCollection:[itemCollection]=[]
append(PersonCollection())

在本例中,CollectionBase类为空,但该类具有更多功能。所以我需要这样。我在答案中增加了一个变体。谢谢Darko,但我需要一个集合中的PersonCollection和AnimalCollection。。。我还认为,这是不可能的。我在过去几天里搜索了一个解决方案,这篇文章是我最后的希望。这不是一个解决方案,因为我在其他函数中需要类型安全CollectionBase类型。即使这样也不可能:collection.append(CollectionBase());对于编译器来说,这也是间接的。
var collection = [AnyObject]()
collection.append(PersonCollection())
collection.append(AnimalCollection())

if collection[0] is PersonCollection {
    // ...
} 
var collection = [CollectionBase<ItemBase>]()
class ItemBase {
}

class PersonItem: ItemBase {
}

class AnimalItem: ItemBase {
}

var collection = [Array<ItemBase>]()

collection.append([PersonItem]())
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())