Может ли расширение базового класса захватывать и возвращать конкретную c реализацию? - PullRequest
0 голосов
/ 25 марта 2020

Предположим, у нас есть:

class BaseClass {
   var id: String
}
class Child1: BaseClass {}
class Child2: BaseClass {}
struct Structure<T : BaseClass> {
    var map = [String: T]()
}

Возможно ли для расширения вернуть указанный тип c?

extension BaseClass {
    static func <- <T : BaseClass>(left: T, right: T) -> Structure<T> where T == Self {
        return Structure(map: [left.id, right])
    }
}

Компилятору не нравится T == Self или левый / правый оператор - T, но вы можете видеть, что я пытаюсь сделать. Я пытаюсь вернуть указанный c тип BaseClass, так что мне нужно реализовать эти операторы только один раз.

Итак, вы можете использовать это так:

var child1 = Child1()
var child11 = Child1()
// the structure returned matches the type of the operator inputs
var structure: Structure<Child1> = child1 + child11

Если я попытаюсь поместить T в оператор left, right, компилятору это тоже не понравится.

Это также не работает (по очевидным причинам), но если бы я мог переписать его, чтобы он работал?

extension BaseClass {
    func combine<T : BaseClass>(with: T) -> Structure<T> {
        // this doesn't work because 'self' can be assumed to be T
        return Structure<T>(map: [self.id : with])
    }
}

1 Ответ

0 голосов
/ 25 марта 2020

Вы можете определить оператора. Вы просто не можете поместить его в тип.

func + <T>(left: T, right: T) -> Structure<T> {
  .init(map: [left.id: right])
}

var structure = Child1() + Child1()

Если вы хотите, чтобы это был метод, вам понадобится протокол.

protocol BaseClassProtocol: BaseClass { }

extension BaseClassProtocol {
  func combine(with instance: Self) -> Structure<Self> {
    .init(map: [id: instance])
  }
}

extension BaseClass: BaseClassProtocol { }

… но если вы у вас будет протокол, вы можете добавить туда и оператора, если хотите.

extension BaseClassProtocol {
  static func + (left: Self, right: Self) -> Structure<Self> {
    .init(map: [left.id: right])
  }

  func combine(with instance: Self) -> Structure<Self> {
    self + instance
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...