Как сделать так, чтобы коллекция generi c работала в конвертировании под капотом в swift? - PullRequest
2 голосов
/ 04 мая 2020

Я реализую обобщенную коллекцию c, и я хотел бы сделать ее использование с иерархией типов / протоколов более удобным. Я наткнулся на следующий вопрос:

Как реализовать коллекцию

class SpecialSet<ObjectType> {

Так, что при двух типах B : A можно выполнить неявное преобразование SpecialSet<B> в SpecialSet<A>?


Я удивлен, но не смог найти никакой документации, объясняющей эту простую концепцию, которая действительно существует для коллекции Array. Этот быстрый код действительно действителен:

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

Я, вероятно, не использовал правильный словарь в своих поисках.

Я попытался определить конструктор следующим образом, но он не позволяет реализовать наследование между двумя родовыми c.

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

1 Ответ

1 голос
/ 04 мая 2020

Это всегда было невозможно.

Обобщения Swift обычно инвариантны, но это типы коллекций стандартной библиотеки Swift, даже если эти типы выглядят как обычные обобщения c типы - используйте магию c, недоступную простым смертным, которая позволяет им быть ковариантными.

Потенциальный обходной путь. 100

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...