在Swift数组中存储通用对象 [英] Storing generic objects in Swift Array

查看:350
本文介绍了在Swift数组中存储通用对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

写下面的小测试:

  class Model {} 
class SubModel:Model {}
class Collection< T:Model> {}

let collection = Collection< SubModel>()
var collections = [Collection]()//也试过[Collection< Model>]()
collections.append (集合)

编译器在append调用失败。消息是:'SubModel'与'Model'不相同。
根据我在泛型中使用的所有其他语言的经验,这应该起作用。作为类型SubMode的集合应该总是可以强制转换为类型Model的集合。
任何人都会遇到这个问题?解决方法?

解决方案

这是因为Swift不支持协方差,例如:

  class Animal {} 
class Cat:Animal {}

Cat 显然是 Animal 的子类型。但是,这并不意味着,例如 Array< Cat> Array< Animal> 的子类型。在支持泛型类型参数(如C#)的协方差的语言中, Array< Cat> 将是 Array< Animal>

在您的具体示例中,您可以使用协议和非泛型集合类来解决此限制。

 协议珍藏{} 
类型号:珍藏{}
类SubModel:Model {}

class Collection {
func append(element:Collectible){
// blah
}
}

var collection = Collection()
collection.append(Model())
collection.append(SubModel())
var collections = [collection]

实际上,对于您的情况,您可以将 Collection 的元素设为一个 Model ,即 func append(element:Model),但我这样做是为了强调协议可以有时用于解决协方差的限制。


Wrote the following little test:

class Model { }
class SubModel : Model {}
class Collection<T: Model> {}

let collection = Collection<SubModel>()
var collections = [Collection]() // Also tried [Collection<Model>]() 
collections.append(collection)

The compiler fails on the append call. The message is: 'SubModel' is not identical to 'Model'. Based on my experience in all other languages I have used with generics, this should work. As a Collection of type SubMode should always be coercible to a Collection of type Model. Anyone run into this? Workarounds?

解决方案

This is happening because Swift does not support covariance in respect of generic type parameters.

For example:

class Animal {}
class Cat : Animal {}

Cat is clearly a subtype of Animal. However, this does not mean that, for instance, Array<Cat> is a subtype of Array<Animal>. In a language that supports covariance for generic type parameters, such as C#, Array<Cat> would be a subtype of Array<Animal>.

In your specific example, you can use a protocol and a non-generic Collection class to get around this limitation. Other situations might require more creativity.

protocol Collectible {}
class Model : Collectible {}
class SubModel : Model {}

class Collection {
    func append(element: Collectible) {
        // blah
    }
}

var collection = Collection()
collection.append(Model())
collection.append(SubModel())
var collections = [collection]

Actually, in your case, you could just make the element of Collection be a Model, i.e., func append(element: Model), but I did it this way to stress that protocols can sometimes be used to get around covariance limitations.

这篇关于在Swift数组中存储通用对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆