Некоторая проблема для хранения универсальной структуры с PAT в массиве - PullRequest
0 голосов
/ 30 октября 2019

У меня есть простой протокол для любого вида расширяемых моделей:

protocol PSDiffableModelProtocol: Hashable {
  var identifier: UUID { get }
}

extension PSDiffableModelProtocol {
  func hash(into hasher: inout Hasher) { hasher.combine(identifier) }

  static func == (lhs: Self, rhs: Self) -> Bool { lhs.identifier == rhs.identifier }
}

Ну и собственно структура, реализующая этот протокол:

struct PSModel1: PSDiffableModelProtocol, Decodable {
    let identifier = UUID()
    let title: String
    let subtitle: String
    let additionalSubtitle: String
    let imageUrl: URL
    let footnote: String?
 }

struct PSModel2: PSDiffableModelProtocol, Decodable { /* ... */ }

// ....

Каждая модель должна храниться в другой распространяемой моделимодель:

struct PSSection<Model: PSDiffableModelProtocol>: PSDiffableModelProtocol {
  let identifier = UUID()
  let title: String?
  let subtitle: String?
  let models: [Model]
}

И тогда возникает простой вопрос, но как мне хранить мои разделы в одном месте? Вот так:

var sections: [PSSection] = [
  PSSection(..., models: [PSModel1(...), PSModel1(...), ]),
  PSSection(..., models: [PSModel2(...), PSModel2(...), ]),
  // ...
]

1 Ответ

0 голосов
/ 30 октября 2019

Вы не можете сохранить [PSSection], потому что компилятор должен знать универсальный тип во время компиляции, а не во время выполнения.

Наиболее предпочтительный подход заключается в использовании Стирание типа

protocol PSDiffableModelProtocol: Hashable {
    var identifier: UUID { get }
}

extension PSDiffableModelProtocol {
    func hash(into hasher: inout Hasher) { hasher.combine(identifier) }

    static func == (lhs: Self, rhs: Self) -> Bool { lhs.identifier == rhs.identifier }
}

struct TodayModel1: PSDiffableModelProtocol, Decodable {
    let identifier = UUID()
    let title: String
    let subtitle: String
    let additionalSubtitle: String
    let imageUrl: URL
    let footnote: String?

    init() {
        title = ""
        subtitle = ""
        additionalSubtitle = ""
        imageUrl = URL(fileURLWithPath: "")
        footnote = ""
    }
}

struct TodayModel2: PSDiffableModelProtocol, Decodable {
    var identifier: UUID = UUID()
}

struct Section<Model: PSDiffableModelProtocol>: PSDiffableModelProtocol {
    let identifier = UUID()
    let title: String?
    let subtitle: String?
    let models: [Model]
}

struct AnyPSDiffableModelProtocol {

    private let _identifier: () -> UUID // or implement a function

    var idenifier: UUID { return _identifier() }

    init<Type: PSDiffableModelProtocol>(_ another: Type) {
        _identifier = { another.identifier }
    }
}

var sections: [AnyPSDiffableModelProtocol] = []


sections.append(.init(Section(title: "title", subtitle: "subtitle", models: [TodayModel1(), TodayModel1()])))
sections.append(.init(Section(title: "title", subtitle: "subtitle", models: [TodayModel2(), TodayModel2()])))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...