Как объявить переменную Equatable? - PullRequest
0 голосов
/ 12 июля 2020
var myDict: [String: Any]

Но в моем случае Any на самом деле не Any. Это либо Int, либо String. Итак, как мне объявить свой var myDict, чтобы показать его Equatable?

var myDict: [String: Any] where Any: Equatable //it doesn't compile

Или что-то вроде этого:)

Ответы [ 2 ]

1 голос
/ 12 июля 2020

Если вы знаете, что это может быть Int или String, используйте тип перечисления IntOrString union. Тип перечисления объединения IntOrString можно сделать равноправным (вам даже не нужен код, вы просто объявляете его):

enum IntOrString : Equatable {
    case int(Int)
    case string(String)
}

Благодаря условному соответствию словарь типа [String: IntOrString] теперь будет Equatable.

0 голосов
/ 12 июля 2020

Я бы порекомендовал создать протокол, моделирующий группировку ваших типов, и расширить эти типы, чтобы они соответствовали этому протоколу.

Например, предположим, что целью этих целых чисел или строк было заполнение ячейки в стол. Вы бы сделали что-то вроде этого:

/// some example type that models a table cell
class Cell {
    var value: String
    
    init(value: String) { self.value = value }
}

protocol CellRepresentable {
    func populate(in: Cell)
}

extension Int: CellRepresentable {
    func populate(in cell: Cell) {
        // Don't ever format numbers for user-consumption like this
        // Use a NumberFormatter. This is for demo use only
        cell.value = String(self)
    }
}

extension String: CellRepresentable {
    func populate(in cell: Cell) {
        cell.value = self
    }
}

let myDict: [String: CellRepresentable] = [
    "key1": 1,
    "key2": "value 2",
    "key3": 3,
]

Ключ в том, чтобы спроектировать протокол так, чтобы он представлял абстракцию (в данном случае что-то, что может быть представлено ячейкой), а не слишком близко моделировать к конкреция (например, деталь хранилища представимого объекта - Int или String).

Преимущество этого подхода в том, что он действительно прост и расширяем. Вы просите эти ценности делать то, что вы от них хотите. Если бы вместо этого вы использовали перечисление, вы не смогли бы этого сделать, вам пришлось бы постоянно писать switch случаев, и вам пришлось бы определять правильное поведение каждого case в каждом сценарии.

Использование подобного полиморфизма означает, что вы можете легко добавить поддержку Bool без необходимости редактировать каждый оператор switch в вашей программе. Полиморфизм просто «заботится об этом».

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