How to allow a generic collection to perform under the hood conversion in swift

血红的双手。 提交于 2021-01-27 19:20:08

问题


I am implementing a generic collection and I would like to make its usage with types/protocol hierarchy more convenient. I stumbled on the following question.

How one does implement a collection

class SpecialSet<ObjectType> {

Such that given two types B : A one can perform implicite conversion of SpecialSet<B> into SpecialSet<A> ?


I am suprised but I wasn't able to find any documentation explaining this simple concept that indeed exist for the Array collection. This swift code is indeed valid:

let b = [B(), B(), B()]
let a: [A] = b

I probably do not used the right vocabulary in my searches.

I tried to define a constructor as follow but it seams not possible to enforce inheritance between two generic.

  init<T>(_ specialSet: SpecialSet<T>) where T: ObjectType {

回答1:


It has always been impossible.

Swift generics are normally invariant, but the Swift standard library collection types — even though those types appear to be regular generic types — use some sort of magic inaccessible to mere mortals that lets them be covariant.

Potential workaround. 🤷‍♂️

protocol Subclass: AnyObject {
  associatedtype Superclass
}

extension B: Subclass {
  typealias Superclass = A
}

class SpecialSet<Object>: ExpressibleByArrayLiteral {
  required init(arrayLiteral _: Object...) { }
  init<T: Subclass>(_: SpecialSet<T>) where T.Superclass == Object { }
}

let specialSetB: SpecialSet = [B(), B()]
let specialSetA = SpecialSet<A>(specialSetB)


来源:https://stackoverflow.com/questions/61597358/how-to-allow-a-generic-collection-to-perform-under-the-hood-conversion-in-swift

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!