写下以下小测试:
class Model { }
class SubModel : Model {}
class Collection<T: Model> {}
let collection = Collection<SubModel>()
var collections = [Collection]() // Also tried [Collection<Model>]()
collections.append(collection)
编译器在追加调用时失败。消息是:'SubModel'与'Model'不同。 根据我在泛型中使用的所有其他语言的经验,这应该有效。作为类型SubMode的集合应该始终可以强制到Model类型的集合。 有人碰到这个吗?解决方法?
答案 0 :(得分:5)
这种情况正在发生,因为Swift在泛型类型参数方面不支持covariance。
例如:
class Animal {}
class Cat : Animal {}
Cat
显然是Animal
的子类型。但是,这并不意味着,Array<Cat>
是Array<Animal>
的子类型。在支持泛型类型参数协方差的语言(例如C#)中,Array<Cat>
将是Array<Animal>
的子类型。
在您的特定示例中,您可以使用协议和非泛型 Collection类来解决此限制。其他情况可能需要更多的创造力。
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]
实际上,在您的情况下,您可以将Collection
的元素设为Model
,即func append(element: Model)
,但我这样做是为了强调协议有时可能是习惯于解决协方差限制。