Common Equatable класс на Swift

Мне нужен контейнер для любого Equatable предметы в НЕGeneric класс (например, начальные классы пользовательского интерфейса из раскадровки). Мне нужно вот так

var items: [Equatable]?

но это не работает, Equatable нужен общий. проблема в том, что не существует общего Equatable учебный класс.


Хорошо - иди в универсальный! Но если я сделаю это

class Item<Value: Equatable>: Equatable {
   var value: Value
   init(_ value: Value) {
       self.value = value
   }
   //Equatable
   public static func ==(lhs: Item, rhs: Item) -> Bool {
       return (lhs.value == rhs.value)
   }
}

тогда я буду вынужден указать тип в моем классе non- Generic-UI. Как это

var items: [Item<WhatShouldBeHere?>]?

но снова мы приходим к проблеме, что не существует общего Equatable учебный класс


Какие-либо решения для контейнера для All Equatable?

1 ответ

Решение

Вместо экзистенциальных типов вам нужно использовать ластик типов:

public struct AnyEquatable: Equatable {
    public let value: Any
    private let equals: (Any) -> Bool

    public init<E: Equatable>(_ value: E) {
        self.value = value
        self.equals = { ($0 as? E) == value }
    }

    public static func == (lhs: AnyEquatable, rhs: AnyEquatable) -> Bool {
        return lhs.equals(rhs.value) || rhs.equals(lhs.value)
    }
}

пример использования:

let items = [
    AnyEquatable(1),
    AnyEquatable(1.23),
    AnyEquatable(true),
    AnyEquatable("some string")
]

let desired = "some string"
let desiredAsAnyEquatable = AnyEquatable(desired)
let desiredDescription = String(reflecting: desired)

for item in items {
    let itemDescription = String(reflecting: item.value)
    let isEqualToDesired = item == desiredAsAnyEquatable
    print("\(itemDescription) is \(isEqualToDesired ? "": "not ")equal to \(desiredDescription)")
}

Пример вывода:

1 не равно "некоторой строке"

1.23 не равно "какой-то строке"

true не равно "некоторой строке"

"некоторая строка" равна "некоторой строке"

Другие вопросы по тегам